Add Dynamic Controls page tests

This commit is contained in:
Mat Hare 2021-07-17 14:41:11 +01:00
parent 7fae4394c1
commit 8c25feb2af
3 changed files with 310 additions and 0 deletions

View File

@ -0,0 +1,66 @@
Feature: Dynamic Controls Page
Background: Open Dynamic Controls page
Given I have navigated to the 'the-internet' "Dynamic Controls" page
Scenario: Verify Dynamic Controls page contents are correct
Then the page title is "Dynamic Controls"
And the opening paragraph text is "This example demonstrates when elements (e.g., checkbox, input field, etc.) are changed asynchronously."
And the page is divided into 2 sections
| section |
| Remove/add |
| Enable/disable |
And there is a horizontal line between the sections
And the Remove/add section contains 1 checkbox and 1 button
And the checkbox label is "A checkbox"
And the checkbox is unchecked
And the button text is "Remove"
And the Enable/disable section contains 1 input control and 1 button
And the input control is blank
And the input control is disabled
And the button text is "Enable"
And a "Fork me on GitHub" banner is displayed in the top-right corner of the page
And the page has a footer containing "Powered by Elemental Selenium"
And the link in the page footer goes to "http://elementalselenium.com/"
Scenario: Click Remove button
When I click the "Remove" button
Then a loading bar is displayed
And the loading bar has a label of "Wait for it..."
And after a few seconds the loading bar disappears
And the checkbox is no longer displayed
And the button text is "Add"
And an "It's gone!" message is displayed
Scenario: Click Add button
Given I have clicked the "Remove" button
And the button text is "Add"
When I click the "Add" button
Then a loading bar is displayed
And the loading bar has a label of "Wait for it..."
And after a few seconds the loading bar disappears
And the checkbox is redisplayed
And the checkbox label is "A checkbox"
And the checkbox is unchecked
And the button text is "Remove"
And an "It's back!" message is displayed
Scenario: Click Enable button
When I click the "Enable" button
Then a loading bar is displayed
And the loading bar has a label of "Wait for it..."
And after a few seconds the loading bar disappears
And the input control is enabled
And the button text is "Disable"
And an "It's enabled!" message is displayed
Scenario: Click Disable button
Given I have clicked the "Enable" button
And the button text is "Disable"
When I click the "Disable" button
Then a loading bar is displayed
And the loading bar has a label of "Wait for it..."
And after a few seconds the loading bar disappears
And the input control is disabled
And the button text is "Enable"
And an "It's disabled!" message is displayed

107
pages/dynamic_controls.py Normal file
View File

@ -0,0 +1,107 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pages.base import BasePage
class DynamicControlsPage(BasePage):
@property
def PAGE_TITLE(self):
return (By.TAG_NAME, 'h4')
OPENING_PARAGRAPH = (By.TAG_NAME, 'p')
SECTION_HEADER = (By.CLASS_NAME, 'subheader')
HORIZONTAL_RULE = (By.XPATH, '//div[@class="example"]/hr')
CHECKBOX_EXAMPLE_FORM = (By.ID, 'checkbox-example')
INPUT_EXAMPLE_FORM = (By.ID, 'input-example')
BUTTON = (By.TAG_NAME, 'button')
CHECKBOX_LABEL = (By.XPATH, './*[@id="checkbox"]')
INPUT = (By.TAG_NAME, 'input')
PARENT = (By.XPATH, './..')
BUTTON = (By.TAG_NAME, 'button')
BUTTON_BY_TEXT = (By.XPATH, '//button[text()="%s"]')
LOADING_BAR = (By.ID, 'loading')
MESSAGE = (By.ID, 'message')
ALTERNATIVE_CHECKBOX = (By.ID, 'checkbox')
def __init__(self, browser):
self.browser = browser
def get_page_title_text(self):
return self.browser.find_element(*self.PAGE_TITLE).text
def get_opening_paragraph_text(self):
return self.browser.find_element(*self.OPENING_PARAGRAPH).text
def get_num_sections(self):
return len(self.browser.find_elements(*self.SECTION_HEADER))
def get_section_headers_text(self):
return [header.text for header in self.browser.find_elements(*self.SECTION_HEADER)]
def get_num_horizontal_rules(self):
return len(self.browser.find_elements(*self.HORIZONTAL_RULE))
def get_section_form(self, section_name):
if section_name == 'Remove/add':
return self.browser.find_element(*self.CHECKBOX_EXAMPLE_FORM)
return self.browser.find_element(*self.INPUT_EXAMPLE_FORM)
def get_num_checkboxes_in_section(self, section_name):
section_form = self.get_section_form(section_name)
return len(section_form.find_elements(*self.INPUT))
def get_num_inputs_in_section(self, section_name):
section_form = self.get_section_form(section_name)
return len(section_form.find_elements(*self.INPUT))
def get_num_buttons_in_section(self, section_name):
section_form = self.get_section_form(section_name)
return len(section_form.find_elements(*self.BUTTON))
def get_checkbox_label(self, section_name):
checkbox = self.browser.find_element(*self.ALTERNATIVE_CHECKBOX)
if (checkbox.tag_name != 'input'):
section_form = self.get_section_form(section_name)
# The label is actually part of the parent div
return section_form.find_element(*self.CHECKBOX_LABEL).text
else:
return checkbox.find_element(*self.PARENT).text
def get_checkbox_checked_state(self, section_name):
section_form = self.get_section_form(section_name)
return section_form.find_element(*self.INPUT).get_attribute('checked') == 'checked'
def get_button_text(self, section_name):
section_form = self.get_section_form(section_name)
return section_form.find_element(*self.BUTTON).text
def get_input_text(self, section_name):
section_form = self.get_section_form(section_name)
return section_form.find_element(*self.INPUT).text
def is_input_enabled(self, section_name):
section_form = self.get_section_form(section_name)
return section_form.find_element(*self.INPUT).is_enabled()
def click_button_by_text(self, buttonText):
self.BUTTON_BY_TEXT = (self.BUTTON_BY_TEXT[0], self.BUTTON_BY_TEXT[1].replace('%s', buttonText))
self.browser.find_element(*self.BUTTON_BY_TEXT).click()
def is_loading_bar_displayed(self):
return self.browser.find_element(*self.LOADING_BAR).is_displayed()
def get_loading_bar_label(self):
return self.browser.find_element(*self.LOADING_BAR).text
def wait_for_loading_bar_to_appear(self):
loading_bar = self.browser.find_element(*self.LOADING_BAR)
WebDriverWait(self.browser, 10).until(EC.visibility_of(loading_bar))
def wait_for_loading_bar_to_disappear(self):
loading_bar = self.browser.find_element(*self.LOADING_BAR)
WebDriverWait(self.browser, 10).until(EC.invisibility_of_element(loading_bar))
def get_message_text(self):
return self.browser.find_element(*self.MESSAGE).text

View File

@ -0,0 +1,137 @@
import pytest
from pytest_bdd import scenarios, given, when, then, parsers
from pages.dynamic_controls import DynamicControlsPage
from sttable import parse_str_table
scenarios('../features/dynamic_controls_page.feature')
SECTIONS = ['Remove/add', 'Enable/disable']
# section = None
@pytest.fixture
def data():
return {}
@given(parsers.parse('I have clicked the "{button_text}" button'))
def click_button_and_wait(browser, data, button_text):
click_button(browser, data, button_text)
DynamicControlsPage(browser).wait_for_loading_bar_to_appear()
DynamicControlsPage(browser).wait_for_loading_bar_to_disappear()
@when(parsers.parse('I click the "{button_text}" button'))
def click_button(browser, data, button_text):
if (button_text == 'Remove' or button_text == 'Add'):
data['section'] = SECTIONS[0]
else:
data['section'] = SECTIONS[1]
DynamicControlsPage(browser).click_button_by_text(button_text)
@then(parsers.parse('the page title is "{title}"'))
def verify_page_title(browser, title):
assert title == DynamicControlsPage(browser).get_page_title_text()
@then(parsers.parse('the opening paragraph text is "{text}"'))
def verify_opening_paragraph_text(browser, text):
assert text == DynamicControlsPage(browser).get_opening_paragraph_text()
@then(parsers.parse('the page is divided into {num:d} sections\n{sections}'))
def verify_section_headers(browser, datatable, num, sections):
assert num == DynamicControlsPage(browser).get_num_sections()
expected = parse_str_table(sections)
for field in expected.fields:
assert expected.columns[field] == DynamicControlsPage(
browser).get_section_headers_text()
@then('there is a horizontal line between the sections')
def verify_horizontal_line_divides_sections(browser):
# This doesn't actually prove the horizontal line lies between the two sections but for now checking such an
#element is present is sufficient
assert 1 == DynamicControlsPage(browser).get_num_horizontal_rules()
@then(parsers.parse('the {section_name} section contains {num_1:d} {control_type} and {num_2:d} button'))
def verify_section_controls(browser, data, section_name, num_1, control_type, num_2):
assert section_name in SECTIONS
assert control_type in ['checkbox', 'checkboxes',
'input control', 'input controls']
data['section'] = section_name
if control_type.startswith('checkbox'):
assert num_1 == DynamicControlsPage(
browser).get_num_checkboxes_in_section(section_name)
else:
assert num_1 == DynamicControlsPage(
browser).get_num_inputs_in_section(section_name)
assert num_2 == DynamicControlsPage(
browser).get_num_buttons_in_section(section_name)
@then(parsers.parse('the checkbox label is "{text}"'))
def verify_checkbox_label(browser, data, text):
assert text == DynamicControlsPage(
browser).get_checkbox_label(data['section'])
@then(parsers.parse('the checkbox is {state}'))
def verify_checkbox_checked_state(browser, data, state):
expected = False
if state == 'checked':
expected = True
assert expected == DynamicControlsPage(
browser).get_checkbox_checked_state(data['section'])
@given(parsers.parse('the button text is "{text}"'))
@then(parsers.parse('the button text is "{text}"'))
def verify_button_text(browser, data, text):
assert text == DynamicControlsPage(
browser).get_button_text(data['section'])
@then('the input control is blank')
def verify_input_control_blank(browser, data):
assert '' == DynamicControlsPage(browser).get_input_text(data['section'])
@then(parsers.parse('the input control is {state}'))
def verify_input_control_status(browser, data, state):
expected = True if state == 'enabled' else False
assert expected == DynamicControlsPage(
browser).is_input_enabled(data['section'])
@then('a loading bar is displayed')
def verify_loading_bar_displayed(browser):
assert True == DynamicControlsPage(browser).is_loading_bar_displayed()
@then(parsers.parse('the loading bar has a label of "{label}"'))
def verify_loading_bar_label(browser, label):
assert label == DynamicControlsPage(browser).get_loading_bar_label()
@then('after a few seconds the loading bar disappears')
def verify_loading_bar_disappears(browser):
DynamicControlsPage(browser).wait_for_loading_bar_to_disappear()
assert False == DynamicControlsPage(browser).is_loading_bar_displayed()
@then('the checkbox is no longer displayed')
def verify_checkbox_not_displayed(browser):
assert 0 == DynamicControlsPage(
browser).get_num_checkboxes_in_section('Remove/add')
@then(parsers.parse('an "{message}" message is displayed'))
def verify_message_text(browser, message):
assert message == DynamicControlsPage(browser).get_message_text()
@then('the checkbox is redisplayed')
def verify_checkbox_displayed(browser):
assert 1 == DynamicControlsPage(
browser).get_num_checkboxes_in_section('Remove/add')