├── README.md ├── modul_1 ├── lesson6_step10_use_assert_and_text.py ├── lesson6_step11_registration.py ├── lesson6_step4_fill_in_the_form.py ├── lesson6_step5_searching_by_text_link.py ├── lesson6_step7_find_elements_method.py └── lesson6_step8_searching_by_xpath.py ├── modul_2 ├── lesson1_step5_checkbox_and_radiobutton.py ├── lesson1_step7_get_attribute.py ├── lesson2_step3_select.py ├── lesson2_step6_execute_script.py ├── lesson2_step8_download.py ├── lesson3_step4_alert_comfirm_prompt.py ├── lesson3_step6_switch_to_window.py ├── lesson4_step8_expected_conditions.py ├── lesson5_step2_mark_smoke_and_regress — копия.py ├── lesson5_step3_mark_win.py ├── lesson5_step4_mark_skip.py ├── lesson5_step5_mark_xpath.py ├── lesson5_step6_mark.py └── lesson5_step7_mark.py ├── modul_3 ├── lesson2_step13_unittest.py ├── lesson2_step8_assert_example.py ├── lesson2_step9_assert_example.py ├── lesson3_step8_pytest_example.py ├── lesson4_step2_fixture_example.py ├── lesson4_step3_fixture_browser.py ├── lesson4_step4_fixture_yield.py ├── lesson4_step5_fixture_function_class_module_session.py ├── lesson4_step6_fixture_autouse.py ├── lesson4_step7_fixture_smile.py ├── lesson6_step10 │ ├── conftest.py │ └── test_items.py └── lesson6_step5.py ├── modul_4_final_project ├── README.md ├── __init__.py ├── conftest.py ├── pages │ ├── base_page.py │ ├── basket_page.py │ ├── locators.py │ ├── login_page.py │ ├── main_page.py │ └── product_page.py ├── pytest.ini ├── requirements.txt ├── test_main_page.py └── test_product_page.py └── snippets_selenium.py /README.md: -------------------------------------------------------------------------------- 1 | ## Автоматизация тестирования с помощью Selenium и Python 2 | 3 | [Курс на Stepik](https://stepik.org/course/575/syllabus) 4 | 5 | `module_1` - Знакомство с Selenium 6 | 7 | `module_2` - Полезные методы Selenium 8 | 9 | `module_3` - Тестовые фреймворки 10 | 11 | `module_4_final_project` - Page Objects. Итоговая работа 12 | 13 | [Шпаргалка](https://drive.google.com/file/d/1aR59-Dos9j8zsrxxG-vt6T_nA4aDYbvV/view?usp=sharing) 14 | -------------------------------------------------------------------------------- /modul_1/lesson6_step10_use_assert_and_text.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | 5 | try: 6 | link = "http://suninjuly.github.io/registration1.html" 7 | browser = webdriver.Chrome() 8 | browser.get(link) 9 | 10 | # Код, который заполняет обязательные поля 11 | name = browser.find_element(By.CLASS_NAME, "form-control.first") 12 | name.send_keys("Sergey") 13 | last_name = browser.find_element(By.CLASS_NAME, "form-control.second") 14 | last_name.send_keys("Konoplev") 15 | email = browser.find_element(By.CLASS_NAME, "form-control.third") 16 | email.send_keys("sergeykonoplev@gmail.com") 17 | 18 | # Отправляем заполненную форму 19 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 20 | button.click() 21 | 22 | # Проверяем, что смогли зарегистрироваться, ждем загрузки страницы 23 | time.sleep(1) 24 | 25 | # Находим элемент, содержащий текст 26 | welcome_text_elt = browser.find_element(By.TAG_NAME, "h1") 27 | # Записываем в переменную welcome_text текст из элемента welcome_text_elt 28 | welcome_text = welcome_text_elt.text 29 | 30 | # С помощью assert проверяем, что ожидаемый текст совпадает с текстом на странице сайта 31 | assert "Congratulations! You have successfully registered!" == welcome_text 32 | 33 | finally: 34 | time.sleep(3) 35 | browser.quit() 36 | -------------------------------------------------------------------------------- /modul_1/lesson6_step11_registration.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | import time 3 | 4 | try: 5 | link = "http://suninjuly.github.io/registration2.html" 6 | browser = webdriver.Chrome() 7 | browser.get(link) 8 | 9 | # Код, который заполняет обязательные поля 10 | browser.find_element_by_css_selector('div.first_block input.first').send_keys('Sergey') 11 | browser.find_element_by_css_selector('div.first_block input.second').send_keys('Konoplev') 12 | browser.find_element_by_css_selector('div.first_block input.third').send_keys('fgbdb@mail.ru') 13 | 14 | # Отправляем заполненную форму 15 | button = browser.find_element_by_css_selector("button.btn") 16 | button.click() 17 | 18 | # Проверяем, что смогли зарегистрироваться 19 | # ждем загрузки страницы 20 | time.sleep(5) 21 | 22 | # Находим элемент, содержащий текст 23 | welcome_text_elt = browser.find_element_by_tag_name("h1") 24 | # Записываем в переменную welcome_text текст из элемента welcome_text_elt 25 | welcome_text = welcome_text_elt.text 26 | 27 | # С помощью assert проверяем, что ожидаемый текст совпадает с текстом на странице сайта 28 | assert "Congratulations! You have successfully registered!" == welcome_text 29 | 30 | finally: 31 | # Ожидание чтобы визуально оценить результаты прохождения скрипта 32 | time.sleep(5) 33 | # Закрываем браузер после всех манипуляций 34 | browser.quit() -------------------------------------------------------------------------------- /modul_1/lesson6_step4_fill_in_the_form.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | 5 | link = "http://suninjuly.github.io/simple_form_find_task.html" 6 | 7 | try: 8 | # Инициализация браузера 9 | browser = webdriver.Chrome() 10 | # Открыли ссылку 11 | browser.get(link) 12 | 13 | # Нашли поле ввода имени по тегу, ввели имя 14 | first_name = browser.find_element(By.TAG_NAME, "input") 15 | first_name.send_keys("Ivan") 16 | # Нашли поле ввода фамилии по имени, ввели фамилию 17 | last_name = browser.find_element(By.NAME, "last_name") 18 | last_name.send_keys("Petrov") 19 | # Нашли поле ввода города по классу, ввели город 20 | city = browser.find_element(By.CLASS_NAME, "form-control.city") 21 | city.send_keys("Smolensk") 22 | # Нашли поле ввода страны по айди, ввели страну 23 | country = browser.find_element(By.ID, "country") 24 | country.send_keys("Russia") 25 | 26 | # Нашли button по классу и кликнули на него 27 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 28 | button.click() 29 | 30 | finally: 31 | # Успеваем скопировать код за 3 секунд 32 | time.sleep(3) 33 | # Закрываем браузер после всех манипуляций 34 | browser.quit() 35 | 36 | # Не забываем оставить пустую строку в конце файла -------------------------------------------------------------------------------- /modul_1/lesson6_step5_searching_by_text_link.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | link = "http://suninjuly.github.io/find_link_text" 7 | answer = str(math.ceil(math.pow(math.pi, math.e)*10000)) 8 | 9 | try: 10 | browser = webdriver.Chrome() 11 | browser.get(link) 12 | 13 | # Переходим по зашифрованной ссылке 14 | button = browser.find_element(By.LINK_TEXT, answer) 15 | button.click() 16 | 17 | # Заполняем форму 18 | name = browser.find_element(By.TAG_NAME, "input") 19 | name.send_keys("Sergey") 20 | last_name = browser.find_element(By.NAME, "last_name") 21 | last_name.send_keys("Konoplev") 22 | city = browser.find_element(By.CLASS_NAME, "form-control.city") 23 | city.send_keys("Penza") 24 | country = browser.find_element(By.ID, "country") 25 | country.send_keys("Russia") 26 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 27 | button.click() 28 | 29 | finally: 30 | time.sleep(5) 31 | browser.quit() 32 | -------------------------------------------------------------------------------- /modul_1/lesson6_step7_find_elements_method.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | 5 | try: 6 | browser = webdriver.Chrome() 7 | browser.get("http://suninjuly.github.io/huge_form.html") 8 | elements = browser.find_elements(By.TAG_NAME, "input") 9 | for element in elements: 10 | element.send_keys("Мой ответ") 11 | 12 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 13 | button.click() 14 | 15 | finally: 16 | time.sleep(30) 17 | browser.quit() 18 | -------------------------------------------------------------------------------- /modul_1/lesson6_step8_searching_by_xpath.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | 5 | link = "http://suninjuly.github.io/find_xpath_form" 6 | 7 | try: 8 | # Инициализация браузера, открытие ссылки 9 | browser = webdriver.Chrome() 10 | browser.get(link) 11 | 12 | # Нашли поле ввода имени 13 | name = browser.find_element(By.XPATH, "//input[@name='first_name']") 14 | name.send_keys("Sergey") 15 | # Нашли поле ввода фамилии 16 | last_name = browser.find_element(By.XPATH, "//input[@name='last_name']") 17 | last_name.send_keys("Konoplev") 18 | # Нашли поле ввода города 19 | city = browser.find_element(By.XPATH, "//input[@class='form-control city']") 20 | city.send_keys("Penza") 21 | # Нашли поле ввода страны 22 | country = browser.find_element(By.XPATH, "//input[@id='country']") 23 | country.send_keys("Russia") 24 | 25 | # Нашли button 26 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 27 | button.click() 28 | 29 | finally: 30 | time.sleep(5) 31 | browser.quit() 32 | -------------------------------------------------------------------------------- /modul_2/lesson1_step5_checkbox_and_radiobutton.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | # Функция, которая считает ответ 7 | def calc(x): 8 | return str(math.log(abs(12*math.sin(int(x))))) 9 | 10 | link = "https://suninjuly.github.io/math.html" 11 | browser = webdriver.Chrome() 12 | browser.get(link) 13 | 14 | try: 15 | # Нашли число по id, поле по классу и ввели число 16 | x = browser.find_element(By.ID, 'input_value') 17 | num = browser.find_element(By.CLASS_NAME, 'form-control') 18 | num.send_keys(calc(int(x.text))) 19 | 20 | # Кликнули чекбокс 21 | checkbox = browser.find_element(By.ID, "robotCheckbox") 22 | checkbox.click() 23 | 24 | # Кликнули радиобатон 25 | radiobutton = browser.find_element(By.ID, "robotsRule") 26 | radiobutton.click() 27 | 28 | # Кликнули submit 29 | button = browser.find_element(By.TAG_NAME, "button") 30 | button.click() 31 | 32 | finally: 33 | time.sleep(5) 34 | browser.quit() 35 | 36 | 37 | -------------------------------------------------------------------------------- /modul_2/lesson1_step7_get_attribute.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | def calc(x): 7 | return str(math.log(abs(12*math.sin(int(x))))) 8 | 9 | link = "http://suninjuly.github.io/get_attribute.html" 10 | browser = webdriver.Chrome() 11 | browser.get(link) 12 | 13 | try: 14 | treasure_value = browser.find_element(By.ID, "treasure") 15 | attribute_treasure = treasure_value.get_attribute("valuex") 16 | 17 | x = attribute_treasure 18 | y = calc(x) 19 | 20 | input_answer = browser.find_element(By.ID, "answer") 21 | input_answer.send_keys(y) 22 | 23 | checkbox_status = browser.find_element(By.ID, "robotCheckbox") 24 | checkbox_status.click() 25 | 26 | radiobutton_status = browser.find_element(By.ID, "robotsRule") 27 | radiobutton_status.click() 28 | 29 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 30 | button.click() 31 | 32 | finally: 33 | time.sleep(5) 34 | browser.quit() 35 | -------------------------------------------------------------------------------- /modul_2/lesson2_step3_select.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | from selenium.webdriver.support.ui import Select 4 | import time 5 | import math 6 | 7 | # Раскрывающиеся (выпадающие) списки. Пример выполнения кода с библиотекой Select. 8 | 9 | link = "http://suninjuly.github.io/selects1.html" 10 | browser = webdriver.Chrome() 11 | browser.get(link) 12 | 13 | try: 14 | # Нашли два элемента и их сумму 15 | num1 = int(browser.find_element(By.ID, "num1").text) 16 | num2 = int(browser.find_element(By.ID, "num2").text) 17 | sum = num1 + num2 18 | 19 | # Выбрали в списке полученную сумму (через спец. библиотеку) 20 | select = Select(browser.find_element(By.TAG_NAME, "select")) 21 | select.select_by_value(str(sum)) 22 | 23 | # Кликнули на кнопку Submit 24 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 25 | button.click() 26 | 27 | finally: 28 | time.sleep(5) 29 | browser.quit() -------------------------------------------------------------------------------- /modul_2/lesson2_step6_execute_script.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | # Метод execute_script, пример прокрутки до нужного элемента 7 | 8 | link = "https://SunInJuly.github.io/execute_script.html" 9 | browser = webdriver.Chrome() 10 | browser.get(link) 11 | 12 | try: 13 | # Нашли число 14 | num = int(browser.find_element(By.ID, "input_value").text) 15 | 16 | # Нашли поле ввода ответа, скролл до нужного элемента и записали ответ 17 | answer = browser.find_element(By.ID, "answer") 18 | browser.execute_script('return arguments[0].scrollIntoView(true);', answer) 19 | answer.send_keys(str(math.log(abs(12*math.sin(num))))) 20 | 21 | # Нашли checkbox, скролл до нужного элемента и поставили галочку 22 | checkbox = browser.find_element(By.ID, "robotCheckbox") 23 | browser.execute_script('return arguments[0].scrollIntoView(true);', checkbox) 24 | checkbox.click() 25 | 26 | # browser.execute_script("window.scrollBy(0, 100);") - как вариант 27 | 28 | # Нашли radiobutton, скролл до нужного элемента и поставили галочку 29 | radiobutton = browser.find_element(By.ID, "robotsRule") 30 | browser.execute_script('return arguments[0].scrollIntoView(true);', radiobutton) 31 | radiobutton.click() 32 | 33 | # Нашли button, скролл до нужного элемента и кликнули на него 34 | button = browser.find_element(By.TAG_NAME, 'button') 35 | browser.execute_script('return arguments[0].scrollIntoView(true);', button) 36 | button.click() 37 | 38 | finally: 39 | time.sleep(5) 40 | browser.quit() -------------------------------------------------------------------------------- /modul_2/lesson2_step8_download.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import os 5 | 6 | # Пример загрузки файла с помощью библиотеки os 7 | 8 | link = "http://suninjuly.github.io/file_input.html" 9 | browser = webdriver.Chrome() 10 | browser.get(link) 11 | 12 | try: 13 | # Ввели имя 14 | first_name = browser.find_element(By.NAME, "firstname") 15 | first_name.send_keys("Sergey") 16 | # Ввели Фамилию 17 | last_name = browser.find_element(By.NAME, "lastname") 18 | last_name.send_keys("Konoplev") 19 | # Ввели имя email 20 | email = browser.find_element(By.NAME, "email") 21 | email.send_keys("sergeyKonoplev@gmail.com") 22 | 23 | # with open("file_example.txt", "w") as file: 24 | # content = file.write("automationbypython") 25 | 26 | current_dir = os.path.abspath(os.path.dirname(__file__)) 27 | file_path = os.path.join(current_dir, "file_example.txt") 28 | browser.find_element(By.ID, "file").send_keys(file_path) 29 | 30 | # Нашли button и кликнули на него 31 | button = browser.find_element(By.CSS_SELECTOR, "button.btn") 32 | button.click() 33 | 34 | finally: 35 | time.sleep(5) 36 | browser.quit() 37 | 38 | -------------------------------------------------------------------------------- /modul_2/lesson3_step4_alert_comfirm_prompt.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | # Пример с выпадающими окнами (alert, comfirm, prompt) 7 | 8 | link = "http://suninjuly.github.io/alert_accept.html" 9 | browser = webdriver.Chrome() 10 | browser.get(link) 11 | 12 | try: 13 | # Клик button 14 | button = browser.find_element(By.TAG_NAME, "button") 15 | button.click() 16 | 17 | # Перешли на выпадающее окно (comfirm) и кликнули "ok" 18 | confirm = browser.switch_to.alert 19 | confirm.accept() 20 | 21 | # Нашли число 22 | num = int(browser.find_element(By.ID, "input_value").text) 23 | 24 | # Нашли поле ввода ответа и записали ответ 25 | answer = browser.find_element(By.ID, "answer") 26 | answer.send_keys(str(math.log(abs(12*math.sin(num))))) 27 | 28 | # Клик button 29 | button = browser.find_element(By.TAG_NAME, 'button') 30 | button.click() 31 | 32 | finally: 33 | time.sleep(5) 34 | browser.quit() 35 | 36 | 37 | -------------------------------------------------------------------------------- /modul_2/lesson3_step6_switch_to_window.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | # Пример перехода на новую вкладку браузера switch_to.window 7 | 8 | link = "http://suninjuly.github.io/redirect_accept.html" 9 | browser = webdriver.Chrome() 10 | browser.get(link) 11 | 12 | try: 13 | # Клик button 14 | button = browser.find_element(By.TAG_NAME, "button") 15 | button.click() 16 | time.sleep(1) 17 | 18 | # Перешли на новую вкладку 19 | browser.switch_to.window(browser.window_handles[1]) 20 | 21 | # Нашли число 22 | num = int(browser.find_element(By.ID, "input_value").text) 23 | 24 | # Нашли поле ввода ответа и записали ответ 25 | answer = browser.find_element(By.ID, "answer") 26 | answer.send_keys(str(math.log(abs(12*math.sin(num))))) 27 | 28 | # Клик button 29 | button = browser.find_element(By.TAG_NAME, 'button') 30 | button.click() 31 | 32 | finally: 33 | time.sleep(5) 34 | browser.quit() -------------------------------------------------------------------------------- /modul_2/lesson4_step8_expected_conditions.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | from selenium.webdriver.support.ui import WebDriverWait 4 | from selenium.webdriver.support import expected_conditions as EC 5 | import math 6 | import time 7 | 8 | # Пример ожидания 9 | 10 | link = "http://suninjuly.github.io/explicit_wait2.html" 11 | browser = webdriver.Chrome() 12 | browser.get(link) 13 | 14 | try: 15 | # Дождаться, когда цена дома уменьшится до 100 баксов 16 | WebDriverWait(browser, 13).until(EC.text_to_be_present_in_element((By.ID, 'price'),'$100')) 17 | 18 | # Нажать на кнопку "Забронировать" 19 | book = browser.find_element(By.ID, "book") 20 | book.click() 21 | 22 | # Решить уже известную нам математическую задачу (используйте ранее написанный код) 23 | num = int(browser.find_element(By.ID, "input_value").text) 24 | answer = browser.find_element(By.ID, "answer") 25 | answer.send_keys(str(math.log(abs(12*math.sin(num))))) 26 | 27 | # Клик button 28 | button = browser.find_element(By.ID, 'solve') 29 | button.click() 30 | 31 | finally: 32 | time.sleep(7) 33 | browser.quit() -------------------------------------------------------------------------------- /modul_2/lesson5_step2_mark_smoke_and_regress — копия.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | # Запустить тест командой pytest -s -v -m smoke test_fixture8.py 6 | 7 | link = "http://selenium1py.pythonanywhere.com/" 8 | 9 | @pytest.fixture(scope="function") 10 | def browser(): 11 | print("\nstart browser for test..") 12 | browser = webdriver.Chrome() 13 | yield browser 14 | print("\nquit browser..") 15 | browser.quit() 16 | 17 | class TestMainPage1(): 18 | @pytest.mark.smoke 19 | def test_guest_should_see_login_link(self, browser): 20 | browser.get(link) 21 | browser.find_element(By.CSS_SELECTOR, "#login_link") 22 | 23 | @pytest.mark.regression 24 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 25 | browser.get(link) 26 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_2/lesson5_step3_mark_win.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | # Запустить тест командой pytest -s -v -m "smoke and win10" test_fixture81.py 6 | 7 | link = "http://selenium1py.pythonanywhere.com/" 8 | 9 | @pytest.fixture(scope="function") 10 | def browser(): 11 | print("\nstart browser for test..") 12 | browser = webdriver.Chrome() 13 | yield browser 14 | print("\nquit browser..") 15 | browser.quit() 16 | 17 | class TestMainPage1: 18 | @pytest.mark.smoke 19 | def test_guest_should_see_login_link(self, browser): 20 | browser.get(link) 21 | browser.find_element(By.CSS_SELECTOR, "#login_link") 22 | 23 | @pytest.mark.smoke 24 | @pytest.mark.win10 25 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 26 | browser.get(link) 27 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_2/lesson5_step4_mark_skip.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | # Результат теста: "1 passed, 1 skipped" 6 | 7 | link = "http://selenium1py.pythonanywhere.com/" 8 | 9 | @pytest.fixture(scope="function") 10 | def browser(): 11 | print("\nstart browser for test..") 12 | browser = webdriver.Chrome() 13 | yield browser 14 | print("\nquit browser..") 15 | browser.quit() 16 | 17 | class TestMainPage1(): 18 | @pytest.mark.skip 19 | def test_guest_should_see_login_link(self, browser): 20 | browser.get(link) 21 | browser.find_element(By.CSS_SELECTOR, "#login_link") 22 | 23 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 24 | browser.get(link) 25 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_2/lesson5_step5_mark_xpath.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | # Запустить тест командой pytest -rX -v test_fixture10b.py 6 | 7 | link = "http://selenium1py.pythonanywhere.com/" 8 | 9 | @pytest.fixture(scope="function") 10 | def browser(): 11 | print("\nstart browser for test..") 12 | browser = webdriver.Chrome() 13 | yield browser 14 | print("\nquit browser..") 15 | browser.quit() 16 | 17 | class TestMainPage1(): 18 | def test_guest_should_see_login_link(self, browser): 19 | browser.get(link) 20 | browser.find_element(By.CSS_SELECTOR, "#login_link") 21 | 22 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 23 | browser.get(link) 24 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") 25 | 26 | @pytest.mark.xfail(reason="fixing this bug right now") 27 | def test_guest_should_see_search_button_on_the_main_page(self, browser): 28 | browser.get(link) 29 | browser.find_element(By.CSS_SELECTOR, "input.btn.btn-default") -------------------------------------------------------------------------------- /modul_2/lesson5_step6_mark.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | # pytest -rx -v test_xfail.py 4 | # Ответ: 1 failed, 1 skipped, 1 xfailed in 0.07s 5 | 6 | @pytest.mark.xfail(strict=True) 7 | def test_succeed(): 8 | assert True 9 | 10 | 11 | @pytest.mark.xfail 12 | def test_not_succeed(): 13 | assert False 14 | 15 | 16 | @pytest.mark.skip 17 | def test_skipped(): 18 | assert False -------------------------------------------------------------------------------- /modul_2/lesson5_step7_mark.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | # Тесты, которые будут найдены и выполнены командой pytest -v -m "smoke and not beta_users" test_task_run_1.py 4 | # Ответ: номер 1 и 4 5 | 6 | class TestMainPage(): 7 | # номер 1 8 | @pytest.mark.xfail 9 | @pytest.mark.smoke 10 | def test_guest_can_login(self, browser): 11 | assert True 12 | 13 | # номер 2 14 | @pytest.mark.regression 15 | def test_guest_can_add_book_from_catalog_to_basket(self, browser): 16 | assert True 17 | 18 | 19 | class TestBasket(): 20 | # номер 3 21 | @pytest.mark.skip(reason="not implemented yet") 22 | @pytest.mark.smoke 23 | def test_guest_can_go_to_payment_page(self, browser): 24 | assert True 25 | 26 | # номер 4 27 | @pytest.mark.smoke 28 | def test_guest_can_see_total_price(self, browser): 29 | assert True 30 | 31 | 32 | @pytest.mark.skip 33 | class TestBookPage(): 34 | # номер 5 35 | @pytest.mark.smoke 36 | def test_guest_can_add_book_to_basket(self, browser): 37 | assert True 38 | 39 | # номер 6 40 | @pytest.mark.regression 41 | def test_guest_can_see_book_price(self, browser): 42 | assert True 43 | 44 | 45 | # номер 7 46 | @pytest.mark.beta_users 47 | @pytest.mark.smoke 48 | def test_guest_can_open_gadget_catalogue(browser): 49 | assert True -------------------------------------------------------------------------------- /modul_3/lesson2_step13_unittest.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | from time import sleep 5 | 6 | data_test = ['Sergey', 7 | 'Konoplev', 8 | 'sergeyKonoplev@gmail.com'] 9 | 10 | class AutoTests(unittest.TestCase): 11 | def test_1(self, link="http://suninjuly.github.io/registration1.html"): 12 | link = link 13 | 14 | with webdriver.Chrome() as browser: 15 | browser.get(link) 16 | 17 | browser.find_element(By.XPATH, "//input[contains(@placeholder, 'first name')]").send_keys(data_test[0]) 18 | browser.find_element(By.XPATH, "//input[contains(@placeholder, 'last name')]").send_keys(data_test[1]) 19 | browser.find_element(By.XPATH, "//input[contains(@placeholder, 'email')]").send_keys(data_test[2]) 20 | sleep(1) 21 | 22 | browser.find_element(By.XPATH, '//button[@type="submit"]').click() 23 | self.assertEqual(browser.find_element(By.TAG_NAME, 'h1').text, 'Congratulations! You have successfully registered!', 'Something went wrong') 24 | 25 | sleep(2) 26 | browser.quit() 27 | 28 | def test_2(self): 29 | self.test_1("http://suninjuly.github.io/registration2.html") 30 | 31 | 32 | if __name__ == '__main__': 33 | unittest.main() 34 | 35 | -------------------------------------------------------------------------------- /modul_3/lesson2_step8_assert_example.py: -------------------------------------------------------------------------------- 1 | def test_input_text(expected_result, actual_result): 2 | assert (expected_result == actual_result), (f"expected {expected_result}, got {actual_result}") -------------------------------------------------------------------------------- /modul_3/lesson2_step9_assert_example.py: -------------------------------------------------------------------------------- 1 | def test_substring(full_string, substring): 2 | assert (substring in full_string), (f"expected '{substring}' to be substring of '{full_string}'") -------------------------------------------------------------------------------- /modul_3/lesson3_step8_pytest_example.py: -------------------------------------------------------------------------------- 1 | 2 | # Прописать в терминале pytest test_abs.py 3 | def test_abs1(): 4 | assert abs(-42) == 42, "Should be absolute value of a number" 5 | 6 | def test_abs2(): 7 | assert abs(-42) == -42, "Should be absolute value of a number" -------------------------------------------------------------------------------- /modul_3/lesson4_step2_fixture_example.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | link = "http://selenium1py.pythonanywhere.com/" 4 | 5 | # Запустить тесты командой pytest -s test_fixture1.py 6 | 7 | class TestMainPage1(): 8 | 9 | @classmethod 10 | def setup_class(self): 11 | print("\nstart browser for test suite..") 12 | self.browser = webdriver.Chrome() 13 | 14 | @classmethod 15 | def teardown_class(self): 16 | print("quit browser for test suite..") 17 | self.browser.quit() 18 | 19 | def test_guest_should_see_login_link(self): 20 | self.browser.get(link) 21 | self.browser.find_element(By.CSS_SELECTOR, "#login_link") 22 | 23 | def test_guest_should_see_basket_link_on_the_main_page(self): 24 | self.browser.get(link) 25 | self.browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") 26 | 27 | 28 | class TestMainPage2(): 29 | 30 | def setup_method(self): 31 | print("start browser for test..") 32 | self.browser = webdriver.Chrome() 33 | 34 | def teardown_method(self): 35 | print("quit browser for test..") 36 | self.browser.quit() 37 | 38 | def test_guest_should_see_login_link(self): 39 | self.browser.get(link) 40 | self.browser.find_element(By.CSS_SELECTOR, "#login_link") 41 | 42 | def test_guest_should_see_basket_link_on_the_main_page(self): 43 | self.browser.get(link) 44 | self.browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_3/lesson4_step3_fixture_browser.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | # Запустить тесты командой pytest -s -v test_fixture2.py 6 | 7 | link = "http://selenium1py.pythonanywhere.com/" 8 | 9 | @pytest.fixture 10 | def browser(): 11 | print("\nstart browser for test..") 12 | browser = webdriver.Chrome() 13 | return browser 14 | 15 | class TestMainPage1(): 16 | # Вызываем фикстуру в тесте, передав ее как параметр 17 | def test_guest_should_see_login_link(self, browser): 18 | browser.get(link) 19 | browser.find_element(By.CSS_SELECTOR, "#login_link") 20 | 21 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 22 | browser.get(link) 23 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_3/lesson4_step4_fixture_yield.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | link = "http://selenium1py.pythonanywhere.com/" 6 | 7 | @pytest.fixture 8 | def browser(): 9 | print("\nstart browser for test..") 10 | browser = webdriver.Chrome() 11 | yield browser 12 | # Этот код выполнится после завершения теста 13 | print("\nquit browser..") 14 | browser.quit() 15 | 16 | class TestMainPage1(): 17 | # Вызываем фикстуру в тесте, передав ее как параметр 18 | def test_guest_should_see_login_link(self, browser): 19 | browser.get(link) 20 | browser.find_element(By.CSS_SELECTOR, "#login_link") 21 | 22 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 23 | browser.get(link) 24 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_3/lesson4_step5_fixture_function_class_module_session.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | link = "http://selenium1py.pythonanywhere.com/" 6 | 7 | @pytest.fixture(scope="class") 8 | def browser(): 9 | print("\nstart browser for test..") 10 | browser = webdriver.Chrome() 11 | yield browser 12 | print("\nquit browser..") 13 | browser.quit() 14 | 15 | class TestMainPage1(): 16 | # Вызываем фикстуру в тесте, передав ее как параметр 17 | def test_guest_should_see_login_link(self, browser): 18 | print("start test1") 19 | browser.get(link) 20 | browser.find_element(By.CSS_SELECTOR, "#login_link") 21 | print("finish test1") 22 | 23 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 24 | print("start test2") 25 | browser.get(link) 26 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") 27 | print("finish test2") -------------------------------------------------------------------------------- /modul_3/lesson4_step6_fixture_autouse.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.by import By 4 | 5 | link = "http://selenium1py.pythonanywhere.com/" 6 | 7 | @pytest.fixture 8 | def browser(): 9 | print("\nstart browser for test..") 10 | browser = webdriver.Chrome() 11 | yield browser 12 | print("\nquit browser..") 13 | browser.quit() 14 | 15 | @pytest.fixture(autouse=True) 16 | def prepare_data(): 17 | print() 18 | print("preparing some critical data for every test") 19 | 20 | class TestMainPage1(): 21 | def test_guest_should_see_login_link(self, browser): 22 | # не передаём как параметр фикстуру prepare_data, но она все равно выполняется 23 | browser.get(link) 24 | browser.find_element(By.CSS_SELECTOR, "#login_link") 25 | 26 | def test_guest_should_see_basket_link_on_the_main_page(self, browser): 27 | browser.get(link) 28 | browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a") -------------------------------------------------------------------------------- /modul_3/lesson4_step7_fixture_smile.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | # Ответ: 5 4 | 5 | @pytest.fixture(scope="class") 6 | def prepare_faces(): 7 | print("^_^", "\n") 8 | yield 9 | print(":3", "\n") 10 | 11 | 12 | @pytest.fixture() 13 | def very_important_fixture(): 14 | print(":)", "\n") 15 | 16 | 17 | @pytest.fixture(autouse=True) 18 | def print_smiling_faces(): 19 | print(":-Р", "\n") 20 | 21 | 22 | class TestPrintSmilingFaces(): 23 | def test_first_smiling_faces(self, prepare_faces, very_important_fixture): 24 | # какие-то проверки 25 | 26 | def test_second_smiling_faces(self, prepare_faces): 27 | # какие-то проверки -------------------------------------------------------------------------------- /modul_3/lesson6_step10/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.chrome.options import Options as ChromeOptions 4 | from selenium.webdriver.firefox.options import Options as FirefoxOptions 5 | 6 | 7 | def pytest_addoption(parser): 8 | parser.addoption('--browser', action='store', default = "chrome", help="Choose browser: chrome or firefox") 9 | parser.addoption('--language', action='store', default="en", help="Choose language: en, ru... etc") 10 | 11 | @pytest.fixture(scope="function") 12 | def browser(request): 13 | browser_name = request.config.getoption("browser") 14 | user_language = request.config.getoption("language") 15 | 16 | if browser_name == "chrome": 17 | print("\nStart Chrome...") 18 | options = ChromeOptions() 19 | options.add_experimental_option('prefs', {'intl.accept_languages': user_language}) 20 | browser = webdriver.Chrome(options=options) 21 | 22 | elif browser_name == "firefox": 23 | print("\nStart Firefox...") 24 | options = FirefoxOptions() 25 | options.set_preference("intl.accept_languages", user_language) 26 | browser = webdriver.Firefox(options=options) 27 | 28 | else: 29 | raise pytest.UsageError("--browser_name should be chrome or firefox") 30 | 31 | 32 | yield browser 33 | print(f"\n{browser_name} quit...") 34 | browser.quit() -------------------------------------------------------------------------------- /modul_3/lesson6_step10/test_items.py: -------------------------------------------------------------------------------- 1 | import time 2 | from selenium.webdriver.common.by import By 3 | from selenium.webdriver.support.ui import WebDriverWait 4 | from selenium.webdriver.support import expected_conditions as EC 5 | 6 | 7 | def test_exist_add_to_cart_button(browser): 8 | browser.get('http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/') 9 | # time.sleep(30) 10 | assert browser.find_element(By.CLASS_NAME, "btn-add-to-basket").is_displayed(), \ 11 | 'Кнопка добавления товара в корзину отсутсвует' 12 | -------------------------------------------------------------------------------- /modul_3/lesson6_step5.py: -------------------------------------------------------------------------------- 1 | import math, time, pytest 2 | from selenium import webdriver 3 | from selenium.webdriver.support.ui import WebDriverWait 4 | from selenium.webdriver.support import expected_conditions as EC 5 | from selenium.webdriver.common.by import By 6 | 7 | # Запус теста: pytest -s -v test5.py 8 | # Ответ: The owls are not what they seem! OvO 9 | 10 | correct_answer = "Correct!" 11 | 12 | def calc(): 13 | answer = math.log(int(time.time())) 14 | return str(answer) 15 | 16 | @pytest.fixture() 17 | def browser(): 18 | browser = webdriver.Chrome() 19 | # browser.implicitly_wait(30) 20 | yield browser 21 | browser.quit() 22 | 23 | @pytest.mark.parametrize('links', ["https://stepik.org/lesson/236895/step/1", 24 | "https://stepik.org/lesson/236896/step/1", 25 | "https://stepik.org/lesson/236897/step/1", 26 | "https://stepik.org/lesson/236898/step/1", 27 | "https://stepik.org/lesson/236899/step/1", 28 | "https://stepik.org/lesson/236903/step/1", 29 | "https://stepik.org/lesson/236904/step/1", 30 | "https://stepik.org/lesson/236905/step/1"]) 31 | 32 | class TestMainPage5(): 33 | def test_lesson4(self, browser, links): 34 | browser.get(links) 35 | time.sleep(7) 36 | 37 | # Авторизовались 38 | browser.find_element(By.ID, "ember33").click() 39 | time.sleep(5) 40 | browser.find_element(By.NAME, "login").send_keys("brownbeer@mail.ru") 41 | browser.find_element(By.NAME, "password").send_keys("Ifevep35))") 42 | browser.find_element(By.CLASS_NAME, "sign-form__btn.button_with-loader").click() 43 | time.sleep(5) 44 | 45 | # Поп-апа с авторизацией больше нет 46 | EC.visibility_of_element_located((By.ID, "ember93")) 47 | time.sleep(5) 48 | 49 | browser.find_element(By.CSS_SELECTOR, ".ember-text-area.ember-view.textarea.string-quiz__textarea").send_keys(calc()) 50 | browser.find_element(By.CSS_SELECTOR, ".submit-submission").click() 51 | WebDriverWait(browser, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".smart-hints__hint"))) 52 | fact_answer = browser.find_element(By.CSS_SELECTOR, ".smart-hints__hint").text 53 | assert fact_answer == correct_answer, f"Answer incorrect! Fact answer: {fact_answer}, expected: {correct_answer}" 54 | 55 | -------------------------------------------------------------------------------- /modul_4_final_project/README.md: -------------------------------------------------------------------------------- 1 | ## Финальный проект 2 | 3 | Тесты запускаются и успешно проходят следующей командой: 4 | 5 | `pytest -v --tb=line --language=en -m need_review` 6 | 7 | Requires python 3.9.1 and higher 8 | -------------------------------------------------------------------------------- /modul_4_final_project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbrownbear/automation_python/449320d701984edb5110a1f9f56c92ac11ec3672/modul_4_final_project/__init__.py -------------------------------------------------------------------------------- /modul_4_final_project/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import time 3 | from selenium import webdriver 4 | from selenium.webdriver.chrome.options import Options as ChromeOptions 5 | from selenium.webdriver.firefox.options import Options as FirefoxOptions 6 | 7 | 8 | def pytest_addoption(parser): 9 | parser.addoption('--browser', action='store', default = "chrome", help="Choose browser: chrome or firefox") 10 | parser.addoption('--language', action='store', default="en", help="Choose language: en, ru... etc") 11 | 12 | @pytest.fixture(scope="function") 13 | def browser(request): 14 | browser_name = request.config.getoption("browser") 15 | user_language = request.config.getoption("language") 16 | if browser_name == "chrome": 17 | print("\nStart Chrome...") 18 | options = ChromeOptions() 19 | options.add_experimental_option('prefs', {'intl.accept_languages': user_language}) 20 | browser = webdriver.Chrome(options=options) 21 | elif browser_name == "firefox": 22 | print("\nStart Firefox...") 23 | options = FirefoxOptions() 24 | options.set_preference("intl.accept_languages", user_language) 25 | browser = webdriver.Firefox(options=options) 26 | else: 27 | raise pytest.UsageError("--browser should be chrome or firefox") 28 | yield browser 29 | #time.sleep(100) 30 | print(f"\n{browser_name} quit...") 31 | browser.quit() 32 | -------------------------------------------------------------------------------- /modul_4_final_project/pages/base_page.py: -------------------------------------------------------------------------------- 1 | from selenium.common.exceptions import NoSuchElementException 2 | from selenium.common.exceptions import NoAlertPresentException 3 | from selenium.common.exceptions import TimeoutException 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | from selenium.webdriver.support import expected_conditions as EC 6 | from .locators import BasePageLocators 7 | from .locators import BasketPageLocators 8 | 9 | import math 10 | 11 | class BasePage: 12 | def __init__(self, browser, url, timeout=5): 13 | self.browser = browser 14 | self.url = url 15 | self.browser.implicitly_wait(timeout) 16 | 17 | # Открытие страницы в браузере 18 | def open(self): 19 | self.browser.get(self.url) 20 | 21 | # Проверка, что элемент существует 22 | def is_element_present(self, how, what): 23 | try: 24 | self.browser.find_element(how, what) 25 | except NoSuchElementException: 26 | return False 27 | return True 28 | 29 | # Проверка, что элемент не существует 30 | def is_not_element_present(self, how, what, timeout=4): 31 | try: 32 | WebDriverWait(self.browser, timeout).until(EC.presence_of_element_located((how, what))) 33 | except TimeoutException: 34 | return True 35 | return False 36 | 37 | # Проверка, что элемент пропал 38 | def is_disappeared(self, how, what, timeout=4): 39 | try: 40 | WebDriverWait(self.browser, timeout, 1, TimeoutException). \ 41 | until_not(EC.presence_of_element_located((how, what))) 42 | except TimeoutException: 43 | return False 44 | return True 45 | 46 | # Получение кодов для прохождения тестовых заданий 47 | def solve_quiz_and_get_code(self): 48 | alert = self.browser.switch_to.alert 49 | x = alert.text.split(" ")[2] 50 | answer = str(math.log(abs((12 * math.sin(float(x)))))) 51 | alert.send_keys(answer) 52 | alert.accept() 53 | try: 54 | alert = self.browser.switch_to.alert 55 | alert_text = alert.text 56 | print(f"Your code: {alert_text}") 57 | alert.accept() 58 | except NoAlertPresentException: 59 | print("No second alert presented") 60 | 61 | # Клик по ссылке авторизации 62 | def go_to_login_page(self): 63 | try: 64 | self.browser.find_element(*BasePageLocators.LOGIN_LINK).click() 65 | except NoSuchElementException: 66 | False 67 | 68 | # Клик по ссылке на карзину 69 | def go_to_basket_page(self): 70 | try: 71 | self.browser.find_element(*BasePageLocators.BASKET_LINK).click() 72 | except NoSuchElementException: 73 | False 74 | 75 | # Поиск ссылки на страницу авторизации 76 | def should_be_login_link(self): 77 | assert self.is_element_present(*BasePageLocators.LOGIN_LINK), "Login link is not presented" 78 | 79 | # Проверка, что юзер авторизован 80 | def should_be_authorized_user(self): 81 | assert self.is_element_present(*BasePageLocators.USER_ICON), "User icon is not presented," \ 82 | " probably unauthorised user" -------------------------------------------------------------------------------- /modul_4_final_project/pages/basket_page.py: -------------------------------------------------------------------------------- 1 | from .base_page import BasePage 2 | from .locators import BasePageLocators 3 | from .locators import BasketPageLocators 4 | from selenium.common.exceptions import NoSuchElementException 5 | from selenium.common.exceptions import TimeoutException 6 | from selenium.webdriver.support.ui import WebDriverWait 7 | from selenium.webdriver.support import expected_conditions as EC 8 | 9 | class BasketPage(BasePage): 10 | def basket_should_be_empty(self): 11 | # Проверка, что корзина пуста 12 | assert self.is_not_element_present(*BasketPageLocators.BASKET_ITEMS), "Basket isn't empty!" 13 | 14 | def should_be_empty_basket_message(self): 15 | # Проверка, что сообщение о пустой корзине отсутствует 16 | try: 17 | assert "Your basket is empty" in self.browser.find_element \ 18 | (*BasketPageLocators.MESSAGE_EMPTY_BASKET).text, "Message is present!" 19 | except NoSuchElementException: 20 | False -------------------------------------------------------------------------------- /modul_4_final_project/pages/locators.py: -------------------------------------------------------------------------------- 1 | from selenium.webdriver.common.by import By 2 | 3 | # Базовые локаторы 4 | class BasePageLocators: 5 | LOGIN_LINK = (By.CSS_SELECTOR, "#login_link") 6 | BASKET_LINK = (By.CSS_SELECTOR, "div.basket-mini.pull-right.hidden-xs>span>a") 7 | USER_ICON = (By.CSS_SELECTOR, ".icon-user") 8 | 9 | # Локаторы с главной страницы 10 | class MainPageLocators: 11 | pass 12 | 13 | # Локаторы со страницы корзины 14 | class BasketPageLocators: 15 | MESSAGE_EMPTY_BASKET = (By.CSS_SELECTOR, "#content_inner>p") 16 | BASKET_ITEMS = (By.CSS_SELECTOR, ".basket-items") 17 | 18 | # Локаторы со страницы авторизации 19 | class LoginPageLocators: 20 | LOGIN_FORM = (By.CSS_SELECTOR, "#login_form") 21 | REGISTER_FORM = (By.CSS_SELECTOR, "#register_form") 22 | REGISTER_EMAIL = (By.CSS_SELECTOR, "#id_registration-email") 23 | REGISTER_PASSWORD_FIRST = (By.CSS_SELECTOR, "#id_registration-password1") 24 | REGISTER_PASSWORD_SECOND = (By.CSS_SELECTOR, "#id_registration-password2") 25 | REGISTER_BUTTON = (By.CSS_SELECTOR, "[name='registration_submit']") 26 | 27 | # Локаторы со страницы продукта 28 | class ProductPageLocators: 29 | ADD_BUTTON = (By.CSS_SELECTOR, ".btn.btn-lg.btn-primary.btn-add-to-basket") 30 | PRODUCT_NAME_IN_MESSAGE = (By.CSS_SELECTOR, "#messages>div:nth-child(1)>.alertinner>strong") 31 | PRODUCT_NAME_IN_BASKET = (By.CSS_SELECTOR, ".col-sm-6.product_main>h1") 32 | BASKET_PRICE = (By.CSS_SELECTOR, ".alertinner > p > strong") 33 | PRODUCT_PRICE = (By.CSS_SELECTOR, ".col-sm-6.product_main>.price_color") 34 | SUCCESS_MESSAGE = (By.CSS_SELECTOR, "#messages > div:nth-child(1)") 35 | -------------------------------------------------------------------------------- /modul_4_final_project/pages/login_page.py: -------------------------------------------------------------------------------- 1 | import time 2 | from .base_page import BasePage 3 | from .locators import LoginPageLocators 4 | 5 | class LoginPage(BasePage): 6 | def should_be_login_page(self): 7 | # Проверка страницы авторизации 8 | self.should_be_login_url() 9 | self.should_be_login_form() 10 | self.should_be_register_form() 11 | 12 | # Проверка url страницы авторизации 13 | def should_be_login_url(self): 14 | assert self.browser.current_url == "http://selenium1py.pythonanywhere.com/en-gb/accounts/login/", f"Login page link is incorrect!" 15 | 16 | # Проверка формы логина 17 | def should_be_login_form(self): 18 | assert self.is_element_present(*LoginPageLocators.LOGIN_FORM), "Login form is not presented" 19 | 20 | # Проверка формы авторизации 21 | def should_be_register_form(self): 22 | assert self.is_element_present(*LoginPageLocators.REGISTER_FORM), "Register form is not presented" 23 | 24 | # Регистрация нового юзера 25 | def register_new_user(self, email, password): 26 | self.browser.find_element(*LoginPageLocators.REGISTER_EMAIL).send_keys(email) 27 | self.browser.find_element(*LoginPageLocators.REGISTER_PASSWORD_FIRST).send_keys(password) 28 | self.browser.find_element(*LoginPageLocators.REGISTER_PASSWORD_SECOND).send_keys(password) 29 | self.browser.find_element(*LoginPageLocators.REGISTER_BUTTON).click() 30 | -------------------------------------------------------------------------------- /modul_4_final_project/pages/main_page.py: -------------------------------------------------------------------------------- 1 | from .base_page import BasePage 2 | from .locators import MainPageLocators 3 | from selenium.webdriver.common.by import By 4 | 5 | class MainPage(BasePage): 6 | def __init__(self, *args, **kwargs): 7 | super(MainPage, self).__init__(*args, **kwargs) 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /modul_4_final_project/pages/product_page.py: -------------------------------------------------------------------------------- 1 | from .base_page import BasePage 2 | from .locators import ProductPageLocators 3 | from selenium.webdriver.common.by import By 4 | 5 | class ProductPage(BasePage): 6 | # Добавление товара в корзину 7 | def add_product_to_basket(self): 8 | self.browser.find_element(*ProductPageLocators.ADD_BUTTON).click() 9 | 10 | # Проверка, что имя товара в корзине и в сообщении совпадают 11 | def product_name_in_message_and_in_basket(self): 12 | name_in_message = self.browser.find_element(*ProductPageLocators.PRODUCT_NAME_IN_MESSAGE).text 13 | name_in_basket = self.browser.find_element(*ProductPageLocators.PRODUCT_NAME_IN_BASKET).text 14 | assert name_in_message == name_in_basket, f"Product name in message ({name_in_message}) and name in basket ({name_in_basket}) aren't equals!" 15 | 16 | # Проверка, что общая стоимость корзины совпадает со стоимостью товара в ней 17 | def basket_cost_equals_product_cost(self): 18 | basket_price = self.browser.find_element(*ProductPageLocators.BASKET_PRICE).text 19 | product_price = self.browser.find_element(*ProductPageLocators.PRODUCT_PRICE).text 20 | assert basket_price == product_price, f"Basket price ({basket_price}) and product price ({product_price}) aren't equals!" 21 | 22 | # Проверка, что сообщение об успешном добавлении товара отсутствует 23 | def should_not_be_success_message(self): 24 | assert self.is_not_element_present(*ProductPageLocators.SUCCESS_MESSAGE), "Message is present!" 25 | 26 | # Проверка, что то сообщение об успешном добавлении товара пропало 27 | def success_message_should_disappear(self): 28 | assert self.is_disappeared(*ProductPageLocators.SUCCESS_MESSAGE), "Message is not disappear!" 29 | 30 | -------------------------------------------------------------------------------- /modul_4_final_project/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | markers = 3 | smoke: marker for smoke tests 4 | regression: marker for regression tests 5 | new: marker for new tests 6 | login_guest: marker for authorized user 7 | need_review: marker fo review -------------------------------------------------------------------------------- /modul_4_final_project/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbrownbear/automation_python/449320d701984edb5110a1f9f56c92ac11ec3672/modul_4_final_project/requirements.txt -------------------------------------------------------------------------------- /modul_4_final_project/test_main_page.py: -------------------------------------------------------------------------------- 1 | from .pages.main_page import MainPage 2 | from .pages.base_page import BasePage 3 | from .pages.basket_page import BasketPage 4 | from .pages.login_page import LoginPage 5 | from selenium.webdriver.common.by import By 6 | import pytest 7 | 8 | link = "http://selenium1py.pythonanywhere.com/" 9 | 10 | @pytest.mark.login_guest 11 | class TestLoginFromMainPage: 12 | def test_guest_can_go_to_login_page(self, browser): 13 | self.page = MainPage(browser, link) 14 | self.page.open() 15 | self.page.go_to_login_page() 16 | self.should_be_login_page() 17 | self.login_page = LoginPage(browser, browser.current_url) 18 | self.login_page.should_be_login_page() 19 | 20 | def test_guest_should_see_login_link(self, browser): 21 | self.page = MainPage(browser, link) 22 | self.page.open() 23 | self.page.should_be_login_link() 24 | 25 | 26 | def test_guest_cant_see_product_in_basket_opened_from_main_page(browser): 27 | page = MainPage(browser, link) 28 | page.open() 29 | page.go_to_basket_page() 30 | basket_page = BasketPage(browser, browser.current_url) 31 | basket_page.basket_should_be_empty() 32 | basket_page.should_be_empty_basket_message() 33 | -------------------------------------------------------------------------------- /modul_4_final_project/test_product_page.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import time 3 | from .pages.product_page import ProductPage 4 | from .pages.main_page import MainPage 5 | from .pages.base_page import BasePage 6 | from .pages.basket_page import BasketPage 7 | from .pages.login_page import LoginPage 8 | from selenium.webdriver.common.by import By 9 | 10 | link_login = "http://selenium1py.pythonanywhere.com/ru/accounts/login/" 11 | link_product = "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/" 12 | 13 | class TestUserAddToBasketFromProductPage: 14 | @pytest.fixture(scope="function", autouse=True) 15 | def setup(self, browser): 16 | self.page_registration = LoginPage(browser, link_login) 17 | self.page_registration.open() 18 | email = str(time.time()) + "@fakemail.org" 19 | password = "673ZF4AjJk34" 20 | self.page_registration.register_new_user(email, password) 21 | self.page_registration.should_be_authorized_user() 22 | 23 | 24 | def test_user_cant_see_success_message(self, browser): 25 | self.product_page = ProductPage(browser, link_product) 26 | self.product_page.open() 27 | self.product_page.should_not_be_success_message() 28 | 29 | @pytest.mark.need_review 30 | def test_user_can_add_product_to_basket(self, browser): 31 | self.product_page = ProductPage(browser, link_product) 32 | self.product_page.open() 33 | self.product_page.add_product_to_basket() 34 | self.product_page.product_name_in_message_and_in_basket() 35 | self.product_page.basket_cost_equals_product_cost() 36 | 37 | 38 | @pytest.mark.xfail 39 | def test_guest_cant_see_success_message_after_adding_product_to_basket(browser): 40 | product_page = ProductPage(browser, link_product) 41 | product_page.open() 42 | product_page.add_product_to_basket() 43 | product_page.should_not_be_success_message() 44 | 45 | 46 | def test_gust_cant_see_success_message(browser): 47 | product_page = ProductPage(browser, link_product) 48 | product_page.open() 49 | product_page.should_not_be_success_message() 50 | 51 | @pytest.mark.need_review 52 | def test_guest_can_add_product_to_basket(browser): 53 | product_page = ProductPage(browser, link_product ) 54 | product_page.open() 55 | product_page.add_product_to_basket() 56 | product_page.product_name_in_message_and_in_basket() 57 | product_page.basket_cost_equals_product_cost() 58 | 59 | @pytest.mark.xfail 60 | def test_message_disappeared_after_adding_product_to_basket(browser): 61 | product_page = ProductPage(browser, link_product) 62 | product_page.open() 63 | product_page.add_product_to_basket() 64 | product_page.success_message_should_disappear() 65 | 66 | def test_guest_should_see_login_link_on_product_page(browser): 67 | link = "http://selenium1py.pythonanywhere.com/en-gb/catalogue/the-city-and-the-stars_95/" 68 | page = ProductPage(browser, link) 69 | page.open() 70 | page.should_be_login_link() 71 | 72 | @pytest.mark.need_review 73 | def test_guest_can_go_to_login_page_from_product_page(browser): 74 | page = ProductPage(browser, link_product) 75 | page.open() 76 | page.go_to_login_page() 77 | 78 | 79 | def test_guest_cant_see_product_in_basket_opened_from_main_page(browser): 80 | link = "http://selenium1py.pythonanywhere.com/" 81 | page = MainPage(browser, link) 82 | page.open() 83 | page.go_to_basket_page() 84 | basket_page = BasketPage(browser, browser.current_url) 85 | basket_page.basket_should_be_empty() 86 | basket_page.should_be_empty_basket_message() 87 | 88 | @pytest.mark.need_review 89 | def test_guest_cant_see_product_in_basket_opened_from_product_page(browser): 90 | page = ProductPage(browser, link_product) 91 | page.open() 92 | page.go_to_basket_page() 93 | basket_page = BasketPage(browser, browser.current_url) 94 | basket_page.basket_should_be_empty() 95 | basket_page.should_be_empty_basket_message() -------------------------------------------------------------------------------- /snippets_selenium.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.by import By 3 | import time 4 | import math 5 | 6 | browser = webdriver.Chrome() 7 | browser.get(link) 8 | 9 | # Работа со списками 10 | 11 | # 12 | # 18 | 19 | # Вариант первый 20 | browser.find_element(By.TAG_NAME, "select").click() # Список раскрылся 21 | browser.find_element(By.CSS_SELECTOR, "option:nth-child(2)").click() # Выбрали нужный элемент 22 | 23 | # Или 24 | browser.find_element(By.CSS_SELECTOR, "[value='1']").click() # Выбрали нужный элемент 25 | 26 | 27 | # Вариант второй 28 | from selenium.webdriver.support.ui import Select # Импортнули специальный класс Select из библиотеки WebDriver 29 | 30 | select = Select(browser.find_element(By.TAG_NAME, "select")) # Инициализировали новый объект, передав в него WebElement с тегом select 31 | select.select_by_value("1") # Ищем элемент с текстом "Python" 32 | 33 | # Или 34 | select.select_by_visible_text("text") # Ищет элемент по видимому тексту 35 | select.select_by_index(1) # Ищет элемент по его индексу или порядковому номеру 36 | # Индексация начинается с нуля. Опция с индексом 0 в данном примере имеет значение по умолчанию равное "--" 37 | 38 | 39 | 40 | 41 | # Метод execute_script 42 | execute_script(javascript_code); 43 | browser.execute_script("alert('Robots at work');") 44 | 45 | # Можно выполнить сразу несколько инструкций 46 | browser.execute_script("document.title='Script executing';alert('Robots at work');") 47 | 48 | # Проскроллить нужный элемент, чтобы он точно стал видимым 49 | "return arguments[0].scrollIntoView(true);" 50 | 51 | # Кликнуть на перекрытую кнопку 52 | button = browser.find_element(By.TAG_NAME, "button") 53 | browser.execute_script("return arguments[0].scrollIntoView(true);", button) 54 | button.click() 55 | 56 | # Вариант второй 57 | button = document.getElementsByTagName("button")[0]; 58 | button.scrollIntoView(true); 59 | 60 | # Можно проскроллить всю страницу целиком на 100 пикселей 61 | browser.execute_script("window.scrollBy(0, 100);") 62 | 63 | 64 | 65 | 66 | # Для загрузки файла на веб-страницу, используем метод send_keys("путь к файлу") 67 | # Три способа задать путь к файлу: 68 | 69 | # 1. вбить руками 70 | element.send_keys("/home/user/stepik/Chapter2/file_example.txt") 71 | 72 | 73 | # 2. задать с помощью переменных 74 | # Указывая директорию, где лежит файл.txt 75 | # В конце должен быть / 76 | directory = "/home/user/stepik/Chapter2/" 77 | 78 | # Имя файла, который будем загружать на сайт 79 | file_name = "file_example.txt" 80 | 81 | # Собираем путь к файлу 82 | file_path = os.path.join(directory, file_name) 83 | # Отправляем файл 84 | element.send_keys(file_path) 85 | 86 | 87 | # 3.путь автоматизатора. 88 | # Если файлы lesson2_7.py и file_example.txt" лежат в одном каталоге 89 | # Импортируем модуль 90 | import os 91 | # Получаем путь к директории текущего исполняемого скрипта lesson2_7.py 92 | current_dir = os.path.abspath(os.path.dirname(__file__)) 93 | 94 | # Имя файла, который будем загружать на сайт 95 | file_name = "file_example.txt" 96 | 97 | # Получаем путь к file_example.txt 98 | file_path = os.path.join(current_dir, file_name) 99 | # Отправляем файл 100 | element.send_keys(file_path) 101 | 102 | # Итоговый код: 103 | import os 104 | from selenium import webdriver 105 | from selenium.webdriver.common.by import By 106 | 107 | link = "http://suninjuly.github.io/file_input.html" 108 | browser = webdriver.Firefox() 109 | browser.get(link) 110 | 111 | current_dir = os.path.abspath(os.path.dirname(__file__)) 112 | file_name = "file_example.txt" 113 | file_path = os.path.join(current_dir, file_name) 114 | element = browser.find_element(By.CSS_SELECTOR, "[type='file']") 115 | element.send_keys(file_path) 116 | 117 | 118 | 119 | 120 | # 2.3. Работа с окнами 121 | # Виды: alert (ок), confirm (ок, отмена), prompt (доп.поле ввода, ок, отмена) 122 | 123 | #Работа с alert 124 | alert = browser.switch_to.alert 125 | alert.accept() 126 | #Получить текст из alert 127 | alert = browser.switch_to.alert 128 | alert_text = alert.text 129 | 130 | #Работа с comfirm 131 | confirm = browser.switch_to.alert 132 | confirm.accept() 133 | confirm.dismiss() 134 | 135 | #Работа с prompt 136 | prompt = browser.switch_to.alert 137 | prompt.send_keys("My answer") 138 | prompt.accept() 139 | 140 | 141 | 142 | 143 | # 2.3. Переход на новую вкладку браузера switch_to.window 144 | browser.switch_to.window(browser.window_handles[1]) # Перейти на следующую страницу 145 | 146 | 147 | 148 | # Явные и неявные ожидания 149 | # Неявное ожидание (Implicit wait) WebDriver ищет каждый элемент в течение 5 секунд 150 | browser.implicitly_wait(5) 151 | 152 | #Явное ожидание (Explicit Waits) проверяет в течение 5 секунд, пока кнопка не станет кликабельной 153 | #Можно использовать until_not 154 | from selenium.webdriver.support import expected_conditions as EC 155 | button = WebDriverWait(browser, 5).until( 156 | EC.element_to_be_clickable((By.ID, "verify"))) 157 | 158 | 159 | 160 | 161 | # Глава 3 162 | # Пирамида тестирования 163 | # 1. Ручные исследовательские тесты 2. Автоматизированные end-to-end тесты 3. Интеграционные тесты 4. Юнит-тесты 164 | 165 | 166 | # Составные сообщения об ошибках 167 | catalog_text = self.catalog_link.text # считываем текст и записываем его в переменную 168 | assert catalog_text == "Каталог", \ 169 | f"Wrong language, got {catalog_text} instead of 'Каталог'" 170 | 171 | # Пример кода проверки 172 | def test_input_text(expected_result, actual_result): 173 | assert (expected_result == actual_result), \ 174 | (f"expected {expected_result}, got {actual_result}") 175 | 176 | # Пример кода проверки 2 177 | def test_substring(full_string, substring): 178 | assert (substring in full_string), (f"expected '{substring}' to be substring of '{full_string}'") 179 | 180 | 181 | 182 | # Pytest 183 | pytest scripts/selenium_scripts 184 | # найти все тесты в директории scripts/selenium_scripts 185 | pytest test_user_interface.py 186 | # найти и выполнить все тесты в файле 187 | pytest scripts/drafts.py::test_register_new_user_parametrized 188 | # найти тест с именем test_register_new_user_parametrized в указанном файле в указанной директории и выполнить 189 | 190 | 191 | 192 | 193 | 194 | # Маркировка тестов и пропуск тестов 195 | 196 | # Запустится только smoke: 197 | @pytest.mark.smoke : pytest -s -v -m smoke test_fixture.py 198 | 199 | # Запуска всех тестов, не отмеченных как smoke: 200 | @pytest.mark.smoke : pytest -s -v -m "not smoke" test_fixture.py 201 | 202 | # Запуск тестов с разными маркировками: 203 | @pytest.mark.smoke 204 | @pytest.mark.regression : pytest -s -v -m "smoke or regression" test_fixture.py 205 | 206 | # Запуск тестов имеющих несколько маркировок: 207 | @pytest.mark.smoke 208 | @pytest.mark.win10 : pytest -s -v -m "smoke and win10" test_fixture.py 209 | 210 | # Пропуск тестов: 211 | @pytest.mark.skip : pytest -s -v test_fixture.py 212 | 213 | # Помечать тест как ожидаемо падающий(пометка:XFAIL): 214 | # упавший тест теперь отмечен как xfail, но результат прогона тестов помечен как успешный 215 | # Когда баг починят, мы это узнаем, так как тест будет отмечен как XPASS 216 | @pytest.mark.xfail : pytest -rx -v test_fixture.py 217 | 218 | # reason - Чтобы увидеть это сообщение в консоли, при запуске нужно добавлять параметр pytest -rX 219 | @pytest.mark.xfail(reason="fixing this bug right now") : pytest -rX -v test_fixture.py 220 | 221 | # Параметр strict 222 | # Ни XFAIL, ни XPASS по умолчанию не приводят к падению всего набора тестов. 223 | # Но это можно изменить, установив параметру strict значение True: 224 | # В этом случае, если тест будет неожиданно пройден (XPASS), 225 | # то это приведет к падению всего тестового набора 226 | @pytest.mark.xfail(strict=True) : pytest -rX -v test_fixture.py 227 | --------------------------------------------------------------------------------