Automatiser des actions avec selenium, pyautogui et xvfb

Rédigé par Fred - - Aucun commentaire

On a parfois besoin de faire des tâches répétitives nécessitant de remplir toujours les mêmes champs, cliquer toujours aux mêmes endroits… Pour automatiser ces actions dans un navigateur, il existe selenium. On peut ainsi naviguer vers une page, récupérer des éléments via xpath, id, nom… puis agir dessus : envoyer des touches, appuyer sur des boutons, etc.

De plus, on peut lancer les scripts dans des serveurs X virtuels comme Xvfb : l’affichage n’est vas visible à l’écran et on peut ainsi utiliser crontab pour lancer les scripts même lorsque notre session est fermée.

Ça ne marche par contre pas quand il y a du des applets java, voire flash, ou pour bouger la souris. Pour cela il faut utiliser d’autres outils, comme sikuli, ou encore plus simple, pyautogui. Par contre il va falloir dire à pyautogui que l’affichage n’est pas celui de notre session, mais celui de xvfb. Pour cela, voir cette réponse sur stackoverflow qui tient en une ligne :

pyautogui._pyautogui_x11._display = Xlib.display.Display(
                os.environ['DISPLAY']
            )

Voici un exemple (pour m’en souvenir) de tout cela combiné :

import pyautogui
import os
import Xlib.display
from time import sleep

from selenium import webdriver
from pyvirtualdisplay.smartdisplay import SmartDisplay

# pour visible=1, installer xserver-xephyr
# sinon, xfvb prend le dessus
display = SmartDisplay(visible=0, size=(800, 600))
display.start()

browser = webdriver.Firefox()
browser.get('https://duckduckgo.com/')
browser.save_screenshot('nrst.png')
print browser.title

search = browser.find_element_by_id('search_form_input_homepage')
search.send_keys("auie")

# la souris se déplace dans le SmartDisplay
pyautogui._pyautogui_x11._display = Xlib.display.Display(
    os.environ['DISPLAY'])
try:
    x, y = pyautogui.locateCenterOnScreen('loupe.png')
    pyautogui.moveTo(x, y, 0.5, pyautogui.easeOutQuad)
    pyautogui.click()
except:
    print "pas trouvé de loupe!"

sleep(3)
browser.save_screenshot('auie.png')
browser.quit()

display.stop()

org-protocol

Rédigé par Fred - - Aucun commentaire

J’avais déjà vu passer l’info, sur irreal.org puis chez Sacha Chua, et ailleurs encore, et à chaque fois, je m’étais dit, faut que je m’y mette. C'est chose faite depuis quelques temps. org-protocol permet d’utiliser org-capture depuis firefox, chrome, acrobat reader, etc.

Ce qui m’intéresse, c’est d’utiliser les bookmarklets de firefox, et plus particulièrement les mots-clés des marque-pages : je tape dans la barre d’adresse ot, or ou on, et ça me rajoute une note au bon endroit dans le bon fichier org-mode.

Je note ici comment j’ai fait. Selon que vous utilisiez windows, ou GNU/Linux, c’est légèrement différent.

Pour windows :

Dans le dossier bin d’emacs, j'ai ajouté le fichier em.cmd contenant :

@echo off
"%~dp0emacsclientw.exe" -na "%~dp0runemacs.exe" -c "%1"

Dans le fichier d’initialisation, init.el, il faut :

;; pour emacs client
(server-start) 

;;; où se situe org-protocol
(add-to-list 'load-path "c:/Users/ftantini/AppData/Roaming/.emacs.d/elpa/org-20150622/")
(require 'org-protocol)

;;; un template
(setq org-protocol-default-template-key "l")
(setq org-capture-templates
 '(("l" "Link" entry (file+olp "C:\\Users\\ftantini\\Documents\\Divers\\orgnotes.org" "Web Links")
        "* %a\n %?\n %i")))

Si on veut plusieurs bookmarks :

(setq org-protocol-default-template-key "l")
(setq org-capture-templates
 '(("t" "Todo" entry (file+headline "C:\\Users\\ftantini\\Documents\\Divers\\orgnotes.org" "Tasks")
        "* TODO %?\n  %i\n  %a")
   ("l" "Link" entry (file+olp "C:\\Users\\ftantini\\Documents\\Divers\\orgnotes.org" "Web Links")
        "* %a\n %?\n %i")
   ("j" "Journal" entry (file+datetree "C:\\Users\\ftantini\\Documents\\Divers\\orgnotes.org")
        "* %?\nEntered on %U\n  %i\n  %a")))

Attention, il a fallu que Web Links soit déjà un header du fichier.

Enfin, il faut également modifier le registre :

REGEDIT4

[HKEY_CLASSES_ROOT\org-protocol]
"URL Protocol"=""
@="URL:Org Protocol"

[HKEY_CLASSES_ROOT\org-protocol\shell]

[HKEY_CLASSES_ROOT\org-protocol\shell\open]

[HKEY_CLASSES_ROOT\org-protocol\shell\open\command]
@="\"c:\\Users\\ftantini\\Progs\\emacs-24.5\\bin\\emacsclientw.exe\" \"%1\""

Côté firefox, on ajoute le bookmarklet suivant :

javascript:location.href='org-protocol://org-capture://l/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection());

où le l qui suit org-capture correspond au template qu’on veut utiliser.

Le sous-protocole n’est, pour moi, pas capture, mais bien org-capture (trouvé grâce à C-h v org-protocol-protocol-alist-default pour voir les protocoles par défaut).

La première fois que le bookmarklet est lancé, il demande avec quoi ouvrir, on renseigne em.cmd.

Pour linux :

C’est très clair ici : http://tech.memoryimprintstudio.com/org-capture-from-external-applications/, les solutions 2, et 3 ont marché pour moi, je vous laisse aller voir et je recopie ce qui marche pour moi (le plugin ne permet d’utiliser qu’un template) :

  • Enregistrer un fichier org-protocol.desktop

dans ~/.local/share/applications avec :

[Desktop Entry]
Name=org-protocol
Exec=emacsclient -c %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
  • Ajouter dans ~/.local/share/applications/mimeapps.list
[Added Associations]
x-scheme-handler/org-protocol=org-protocol.desktop

puis mettre à jour :

update-desktop-database ~/.local/share/applications/

(le paquet pour debian est desktop-file-utils)

Côté Emacs, dans le fichier d’initialisation, init.el, on ajoute (si ce n’est pas déjà présent) :

;; pour emacs client
(server-start) 

;;; org-protocol
(require 'org-protocol)

(setq org-protocol-default-template-key "l")
(setq org-capture-templates
 '(("l" "Link"                entry (file+headline "/home/fred/Data/Donnees/Org/Notes/orgnotes.org" "trouvailles")
        "* %a\n %?\n %i")))

Et si on veut plusieurs bookmarks :

(setq org-protocol-default-template-key "l")
(setq org-capture-templates
 '(("t" "Todo" entry (file+headline "/home/fred/Data/Donnees/Org/Notes/orgnotes.org" "Tasks")
        "* TODO %?\n  %i\n  %a")
   ("l" "Link" entry (file+olp "/home/fred/Data/Donnees/Org/Notes/orgnotes.org" "Web Links")
        "* %a\n %?\n %i")
   ("j" "Journal" entry (file+datetree "/home/fred/Data/Donnees/Org/Notes/orgnotes.org")
        "* %?\nEntered on %U\n  %i\n  %a")))

Comme pour windows, le header (Tasks, Web Links) doit déjà être présent.

Le bookmarklet qui va bien à ajouter dans firefox :

javascript:location.href='org-protocol://capture://l/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection());

où le l qui suit org-capture correspond au template qu’on veut utiliser.

Par contre, cette fois le sous-protocole est bien capture, et pas org-capture, et je n’ai pas chercher à comprendre pourquoi… (org-protocol-protocol-alist-default est pourtant le même.)

Pour tester, on peut, en ligne de commande, lancer

emacsclient org-protocol://capture://x/toto/tata/titi

si ça ne marche pas correctement, par exemple, si le buffer s’ouvre avec comme nom le dernier argument (ici titi), c’est sûrement un souci de sous-protocole.

Mes templates

Voilà les trois templates qui sont chez moi associés à un bookmarklet :

(setq org-capture-templates
      '(("t" "notes-info/travail"
               entry (file+headline "/home/fred/Data/Donnees/Org/Notes/notes-info.org" "trouvailles")
               "** COMMENCÉ %:description\n%i\n%?\nSource : %a\n\n" :immediate-finish)
        ("r" "notes-info/raccourcis"
               entry (file+headline "/home/fred/Data/Donnees/Org/Notes/notes-info.org" "raccourcis")
               "** COMMENCÉ %:description\n%i\n%?\nSource : %a\n\n" :immediate-finish)
        ("l" "notes/à lire"
               entry (file+headline "/home/fred/Data/Donnees/Org/Notes/notes.org" "à lire")
;              "* %^{Title}\n\n  Source: %u, %c\n\n  %i"))))
               "** %a\n%i\n%?\n\n" :immediate-finish)
        ))
                                        ;%:description : titre de la page
                                        ;%i : sélection de la page web
                                        ;%? : curseur pour continuer de remplir la note
                                        ;%a : [[lien][titre de la page]]

Je rappelle les liens de l’intro : chez Sacha Chua, qui explique comment elle a fait pour chrome, et le site d’orgmode, en particulier, les templates : http://orgmode.org/manual/Capture-templates.html pour avoir d’autres variables (%T, %k, %^{Title}, %^C… sur Template-expansion), et la page de départ : http://orgmode.org/worg/org-contrib/org-protocol.html.

Besoin de se dégourdir les doigts ?

Rédigé par Fred - - 4 commentaires

Parfois on a (j’ai) envie de coder (ou faire coder des étudiants) et on ne sait pas quoi faire — ou alors on veut s’entrainer, tester de nouvelles choses. Voici une liste non-exhaustive de sites web — non testés pour la plupart — qui proposent des exercices pour apprendre à programmer, des défis pour faire s’affronter des programmes, voire pour gagner de l’argent (mais ce n’est pas le sujet).

Lire la suite de Besoin de se dégourdir les doigts ?

Python Module of the Week

Rédigé par Fred - - Aucun commentaire

Note pour moi-même.

Les modules des « module python de la semaine » : https://pymotw.com/2/contents.html

Par ordre alphabétique : https://pymotw.com/2/py-modindex.html

Pour info, pymotw est/était la présentation par Doug Hellmann d’un module python avec des exemples de codes. Les sources sont disponibles sur bitbucket.

Pour python 3 : https://pymotw.com/3/

Quelques notes SoapUI

Rédigé par Fred - - Aucun commentaire

Voici un premier article sur SoapUI. Un second arrivera prochainement :]

Les informations sont un peu brutes, cela me sert surtout de notes. Du coup, c’est directement technique et suppose que vous connaissiez déjà SoapUI. D’abord un « rappel » sur les property expansions puis comment on peut passer des paramètres entre les différents pas du cas de test et comment faire des assertions variables.

Lire la suite de Quelques notes SoapUI

Fil RSS des articles de cette catégorie