Introduciamo ora il discorso delle Action API. Sinora abbiamo imparato ad interagire con Selenium nella maniera più canonica: abbiamo immaginato di scrivere un programma in grado di far finta di essere un utente umano. Il risultato è stato piuttosto soddisfacente e ci ha permesso di guadagnarci tutte le abilità principali per poter scrivere dei test su pagine web.
Quello che è successo ci ha permesso però di agire ad alto livello ossia ordinando delle azioni che non facessero riferimento a dispositivi hardware come tastiera e mouse. In pratica, ciò che sappiamo fare è dare a Selenium istruzioni di questo tipo:
- individua un elemento nella pagina web con caratteristiche identificabili con uno schema riconducibile a selettori CSS, ID, query XPATH o altro ancora;
- svolgi sull'elemento una specifica azione come click o immissione di testo.
- estrai i risultati dopo eventuale attesa.
Quando usare le Action API
Tutto ciò rappresenta il modo principale di lavorare con Selenium. A volte però potrebbe capitare la necessità di dover dare delle indicazioni più specifiche, lavorare più a "basso livello" ovvero con una minore distanza dagli hardware di input (tastiere, mouse, etc.).
Per rendere tutto ciò agevole, sono state introdotte le cosiddette Action API, funzioni che permettono di dare comandi nel dettaglio arrivando a specificare singole microazioni come il movimento del puntatore del mouse. Conosciamole meglio.
Caratteristiche di fondo delle Actions API
Il loro aspetto più importante verte sulla necessità di comprendere esattamente cosa sono queste funzionalità e cosa riguardano. Diciamo innanzitutto che sono attivabili mediante ActionChains
e spesso gioveranno della possibilità di indicare singoli pulsanti della tastiera con Keys
(attività peraltro utile in molti test da svolgere con Selenium). Pertanto, tra i vari import
, per lavorare con questo set di funzionalità utilizzeremo i seguenti:
from selenium.webdriver import Keys, ActionChains
Come vediamo, stiamo parlando di qualcosa perfettamente contestualizzato e integrato all'interno del framework.
Le catene
Altra caratteristica importante di queste funzionalità consiste nel fatto che sono costituite da catene (intuibile dal suffisso chains dell'elemento nominato poco fa). Una singola catena sarà quindi costituita da una sequenza di operazioni, concatenate tra loro, che termineranno con l'invocazione del metodo perform
che decreterà l'avvio di tutto ciò che essa prevede.
Vediamo un esempio. Diciamo che abbiamo a che fare con un pagina web con un campo di ricerca in cui dovremo scrivere del testo e subito dopo dovremo premere il tasto Invio per inoltrare la richiesta.
Tutta la fase di ricerca degli elementi non è peculiare delle Actions API pertanto per individuare il campo form della pagina web e leggere i risultati ottenuti non faremo altro che usare come sempre find_element
e find_elements
.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
driver = webdriver.Chrome()
# inserire URL da contattare
URL="..."
driver.get(URL)
# supponiamo di accedere al campo con ID search-field
elem = driver.find_element(By.ID, "search-field")
ActionChains(driver)\
.send_keys_to_element(elem, "keyword da cercare")\
.send_keys(Keys.RETURN)\
.perform()
# da qui ricominciamo con tipico codice di navigazione tra i risultati
elem = driver.find_elements(....)
# elaborazioni varie
# chiusura del driver
driver.close()
Come si vede abbiamo attivato una catena di azioni in cui abbiamo inserito il codice all'interno del campo e abbiamo richiesto la pressione del tasto "Invio". Tutto ciò che è successo prima della chain, e che succederà dopo includendo waiting e lettura dei risultati, verrà trattato normalmente con le funzionalità di Selenium che abbiamo studiato nelle altre lezioni.
Tipologie di Action
Le Action API sono delle funzionalità particolari, molto utili, ma anche molto estese. Quindi non possiamo trattarle approfonditamente in questa guida. A livello orientativo, si sappia che in base al dispositivo a cui si rivolgono sono suddivisibili in varie categorie tra cui:
- azioni per la tastiera: includono tutto ciò che riguarda la pressione di tasti (
send_keys
) contemplando anche la possibilità di selezionare la singola pressione di un tasto (key_down
) ed il rilascio dello stesso (key_up
); - azioni per la gestione del mouse: includono la pressione di tasti sia normale sia prolungata sia con un doppio click (metodi
click
,click_and_hold
,double_click
) nonché il movimento del puntatore con azioni comemove_to_element_with_offset
emove_to_element
; - azioni per pen stylus (potremmo dire, in generale, una penna per touch screen) in cui possiamo dettare azioni con sequenze come "poggia la punta", "effettua un movimento", "alza la punta" con, in ordine, i metodi
pointer_down
,move_by
epointer_up
; - azioni per la rotella del mouse tra cui una serie di opzioni per lo scrolling (metodi
scroll_to_element
,scroll_by_amount
,scroll_from_origin
).
Ruolo delle Actions API
La Actions API sono funzionalità estremamente interessanti in quanto permettono di svolgere operazioni impossibili altrimenti. Ma che ruolo hanno nella nostra preparazione di tester di pagine web? Sicuramente non devono essere il primissimo approccio nei test in quanto per simulare il comportamento di un essere umano si può agire come abbiamo imparato con le operazioni high level che si basano per lo più sulla selezione di elementi e l'interazione con essi.
Quando però abbiamo bisogno di mimare il comportamento dell'utente non tanto in rapporto alla pagina web ma in rapporto agli strumenti di immissione di input, lì allora potremo ricorrere con grande soddisfazione alle Actions API.
In tal caso potremmo dire che non staremo emulando ciò che l'utente fa ma e non cosa stanno facendo le sue mani!