Selenium Basics
Selenium Webdriver Architecture
+--------------+ +-----------+ +---------+
| | | | | |
| Test Scripts |-------->| Webdriver |-------->| Browser |
| | | | | |
+--------------+ +-----------+ +---------+
Installation
Nainštalujte si do svojho prostredia balíček
selenium
Ak používate nástroj
pip
, stačí jednoducho napísať z príkazového riadku:pip install selenium
V prostredí PyCharm zasa balíček nainštalujete v nastaveniach používaného interpretera jazyka Python.
Nainštalujte si príslušný WebDriver pre váš prehliadač.
Ak používate linuxovú distribúciu Fedora, môžete priamo z príkazového riadku nainštalovať balíček
chromedriver
. Tento obsahuje WebDriver pre prehliadač Chrome:sudo dnf install chromedriver
Ak používate linuxovú distribúciu Ubuntu, z príkazového riadku nainštalujte balík
chromium-webdriver
príkazom:sudo apt install chromium-webdriver
Ak používate OS Windows a máte nainštalovaný balíčkovací systím Chocolatey, webDriver pre prehliadač Chromium si môžete doinštalovať príkazom:
choco install chromedriver
WebDriver pre ostatné systémy môžete stiahnuť a nainštalovať podľa pokynov na domovskej stránke http://www.seleniumhq.org/download/
Poznámka: Ak používate OS Windows, váš stiahnutý webdriver si rozbaľte do priečinku, v ktorom sa nachádza interpreter jazyka Python (súbor
python.exe
). Vyhnete sa tak situácii, kedy budete musieť pri každej inštancii uvádzať absolútnu cestu k nemu.
The Basics
Začneme s jednoduchou ukážkou:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()
Creating Tests with pytest
Z predchádzajúcej ukážky si vytvoríme niekoľko testov.
Vytvorte súbor
test_pythonorg.py
, ktorý bude obsahovať jednotlivé testy.from selenium import webdriver from selenium.webdriver.common.keys import Keys
Vytvorte test, pomocou ktorého overíte, či sa v názve stránky www.python.org nachádza slovo
Python
def test_when_enter_page_check_title_contains_python(): driver = webdriver.Chrome() driver.get("http://www.python.org") assert 'Python' in driver.title driver.close()
Overte, či po zadaní kľúčového výrazu pycon do vyhľadávača na tejto stránke, sa na stránke zobrazí element
<h3>
s textomResults
def test_when_search_string_entered_then_results_must_be_on_page(): driver = webdriver.Chrome() driver.get("http://www.python.org") element = driver.find_element_by_name('q') element.send_keys('selenium') element.submit() results = driver.find_element_by_xpath('//*[@id="content"]/div/section/form/h3 ') assert results.text == 'Results' driver.close()
Pre vytvorený testcase vytvorte potrebné fixtures a podľa potreby upravte aj zvyšný kód.
@fixture def driver(): driver = webdriver.Chrome() driver.get('http://www.python.org') yield driver driver.close() def test_when_enter_page_check_title_contains_python(driver): assert 'Python' in driver.title def test_when_search_string_entered_then_results_must_be_on_page(driver): element = driver.find_element_by_name('q') element.send_keys('pycon sk 2019') element.submit() results = driver.find_element_by_xpath('//*[@id="content"]/div/section/form/h3 ') assert results.text == 'Results'
Odoslanie formuláru môže byť samozrejme niekoľkými spôsobmi:
pomocou nového riadka na konci vstupu:
element.send_keys('pycon sk 2019\n')
pomocou explicitne zadanej klávesy po celom vstupe:
element.send_keys('pycon sk 2019', Keys.RETURN)
pomocou kliknutia na tlačidlo vedľa vyhľadávacieho poľa:
driver.find_element_by_id('submit').click()
Upravte scope pre fixture tak, aby sa prehliadač otvoril pre všetky testy len raz.
@fixture(scope='module')
Testing of Login Form
import unittest
from selenium import webdriver
class AzetSkTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.get('http://www.azet.sk')
@classmethod
def tearDownClass(cls):
cls.driver.quit()
def test_if_password_input_field_exists(self):
self.driver.find_element_by_name('form[password]')
def test_if_login_input_field_exists(self):
self.driver.find_element_by_name('form[username]')
def test_if_the_input_field_login_is_writable(self):
self.driver.find_element_by_name('form[username]').send_keys('username')
def test_if_the_input_field_password_is_writable(self):
self.driver.find_element_by_name('form[password]').send_keys('password')
def test_if_there_are_asterisks_in_password_field(self):
pass
def test_if_correct_page_after_successfull_login(self):
pass
def test_if_login_page_remains_after_wrong_credentials_have_been_provided(self):
pass
def test_if_it_is_possible_to_submit_empty_form(self):
pass
Tips and Tricks
Problém s nájdením Webdriver-a
Ak chromedriver
nespustíte priamo z príkazového riadku, musíte pri vytváraní objektu driver-a k nemu uviesť absolútnu cestu. Tento prístup použijete vtedy, ak ste používateľom distribúcie Ubuntu:
driver = webdriver.Chrome(executable_path='/path/to/webdriver')
Webdriver v Headless režime
Prehliadač Chrome je možné spustiť v tzv. headless režime, kedy sa nebude spúšťať s grafickým rozhraním, ale spustí sa len v pamäti. To je veľmi výhodné v prípadoch, ak chcete testy spúšťať na pozadí bez nutnosti mať spustené grafické prostredie.
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(options=options)
Testing Special HTML Elements
Checkboxes
So zaškrtávacie políčkom sa pracuje ako so štandardným elementom. Bude nás akurát zaujímať, ako zistiť jeho stav (zaškrtnuté alebo nezaškrtnuté) a tiež nás bude zaujímať, ako toto políčko označiť.
Začnime teda jeho nájdením na stránke pomocou XPath-u:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://blazedemo.com')
# search checkbox by xpath
element = driver.find_element_by_xpath('//input[@id="rememberMe"]')
Zistiť, či je alebo nie je políčko zaškrtnuté, môžeme pomocou metódy element.is_selected()
. Vráti hodnotu True
alebo False
na základe toho, či je alebo nie je toto políčko zaškrtnuté.
Zaškrtnúť alebo odškrtnúť ho je zasa možné zavolaním metódy element.click()
.
Radio Buttons
S radio tlačidlami sa pracuje podobne ako v prípade zaškrtávacích polí. Sú to teda elementy, ktoré vieme v HTML dokumente vyhľadať pomocou ich označenia o opýtať sa, či sú alebo nie sú označené. Keďže sa však jedná o skupinu elementov, v ktorej môže byť vo výsledku označený len jeden, je ešte potrebné sa dostať k hodnote, ktorú radio button má.
Začneme teda tým, že si uvedenú množinu radio tlačidiel na stránke nájdeme pomocou XPath-u:
from selenium import webdriver
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get('http://www.seleniumeasy.com/test/basic-radiobutton-demo.html')
# search radio buttons by xpath
radios = driver.find_elements_by_xpath('//input[@type="radio" and @name="ageGroup"]')
Označiť niektorý z nich môžeme zavolať volaním metódy .click()
na príslušnom elemente:
for radio in radios:
radio.click()
Ak chceme zistiť, či je element označený, budeme sa nad ním pýtať metódou .is_selected()
. Hodnotu zo atribútu value
zvoleného elementu získame volaním metódy .get_attribute()
:
for radio in radios:
if radio.is_selected():
print(radio.get_attribute('value'))
break
else:
print('No value is selected')
Dropdown Menus
Pre prácu s dropdown budeme používať triedu Select
. Pracovať je síce možné aj bez neho, ale je to potom surové a neintuitívne. Týmto spôsobom budeme mať k dispozícii metódy, ktoré môžeme rovno využiť.
from selenium import webdriver
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get('http://blazedemo.com')
Začneme tým, že vytvoríme objekt Select
, ktorý bude reprezentovať práve rozbaľovacie menu (dropdown, combo box, select). Do konštruktora vstupuje objekt elementu tohto prvku, ktorý identifikujeme napr. pomocou XPath-u:
# get select element based
select = Select(driver.find_element_by_xpath('//select[@name="fromPort"]'))
Ak sa chceme pozrieť, aké všetky možnosti (elementy <option>
) k dispozícii máme, môžeme ich prejsť v cykle:
for option in select.options:
print(option.text)
Vyberať, resp. označovať jednotlivé voľby môžeme podľa
- viditeľného textu
- hodnoty
- indexu
Ukážky sa nachádzajú nižšie:
# select by visible text
select.select_by_visible_text('Portland')
# select by value
select.select_by_value('Boston')
# select by index
select.select_by_index(4)
Ak nás naopak zaujíma, čo je zvolené, môžeme využiť dve properties:
select.first_selected_option
- The first selected option in this select tag (or the currently selected option in a normal select).select.all_selected_options
- Returns a list of all selected options belonging to this select tag.
Sending Keys
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get('http://www.python.org')
elem = driver.find_element_by_xpath('//input')
elem.send_keys('pycon', Keys.RETURN)
TODO
References
- Selenium with Python
- http://naucse.python.cz/lessons/intro/testing/
- Selenium WebDriver
- Selenium Easy - stránky, kde sa dá testovať Selenium