diff --git a/app/application.py b/app/application.py index fd25d6d1d..332f010fb 100644 --- a/app/application.py +++ b/app/application.py @@ -1,6 +1,7 @@ from pages.bestsellers_page import BestsellersPage from pages.main_page import MainPage from pages.search_results_page import SearchResultsPage +from pages.signin_page import SignInPage class Application: @@ -10,3 +11,4 @@ def __init__(self, driver): self.bestsellers_page = BestsellersPage(self.driver) self.main_page = MainPage(self.driver) self.search_results_page = SearchResultsPage(self.driver) + self.sign_in_page = SignInPage(self.driver) diff --git a/features/steps/amazon_main_page_steps.py b/features/steps/amazon_main_page_steps.py index 6e872a020..2d180c502 100644 --- a/features/steps/amazon_main_page_steps.py +++ b/features/steps/amazon_main_page_steps.py @@ -25,6 +25,46 @@ def click_sign_in(context): e.click() +@when('Wait for {sec} sec') +def wait_sec(context, sec): + sleep(int(sec)) + + +@when('Click Orders') +def click_orders(context): + context.app.main_page.click_returns_and_orders_btn() + + +@when('Hover over language options') +def hover_lang(context): + context.app.main_page.hover_lang() + + +@when('Select department by value {selection_value}') +def select_department(context, selection_value): + context.app.main_page.select_department(selection_value) + + +@then('Verify {department} department is selected') +def verify_department(context, department): + context.app.search_results_page.verify_department(department) + + +@then('Verify Spanish option present') +def verify_lang(context): + context.app.main_page.verify_lang() + + +@then('Verify Sign In is clickable') +def verify_sign_in_clickable(context): + context.driver.wait.until(EC.element_to_be_clickable(SIGN_IN), message='Sign in not clickable') + + +@then('Verify Sign In disappears') +def verify_sign_in_btn_disappear(context): + context.driver.wait.until(EC.invisibility_of_element_located(SIGN_IN), message='Sign in is still visible') + + @then('Verify hamburger menu is present') def verify_ham_menu_present(context): context.driver.find_element(*HAM_MENU) diff --git a/features/steps/search_results_page_steps.py b/features/steps/search_results_page_steps.py index a0885d878..5c35a465e 100644 --- a/features/steps/search_results_page_steps.py +++ b/features/steps/search_results_page_steps.py @@ -1,8 +1,33 @@ from selenium.webdriver.common.by import By from behave import given, when, then +from time import sleep + +PRODUCT_PRICE = (By.XPATH, "//div[@data-component-type='s-search-result']//a[.//span[@class='a-price']]") +SEARCH_RESULTS = (By.CSS_SELECTOR, "[data-component-type='s-search-result']") +PRODUCT_TITLE = (By.CSS_SELECTOR, 'h2 span.a-text-normal') +PRODUCT_IMG = (By.CSS_SELECTOR, ".s-image[data-image-latency='s-product-image']") @then('Search results for {expected_result} are shown') def verify_search_results(context, expected_result): - actual_result = context.driver.find_element(By.XPATH, "//span[@class='a-color-state a-text-bold']").text - assert expected_result == actual_result, f'Error! Expected {expected_result}, but got {actual_result}' + # actual_result = context.driver.find_element(*SEARCH_RESULTS).text + # assert expected_result == actual_result, f'Error! Expected {expected_result}, but got {actual_result}' + context.app.search_results_page.verify_search_results(expected_result) + + +@when('Click on the first product') +def click_first_product(context): + context.driver.find_element(*PRODUCT_PRICE).click() + sleep(2) + + +@then('Verify that every product has a name and an image') +def verify_products_name_img(context): + all_products = context.driver.find_elements(*SEARCH_RESULTS) + print(all_products) + + for product in all_products: + title = product.find_element(*PRODUCT_TITLE).text + print(title) + assert title, 'Error! Title should not be blank' + assert product.find_element(*PRODUCT_IMG).is_displayed(), 'Img is not found' diff --git a/features/steps/sign_in_steps.py b/features/steps/sign_in_steps.py index 6fb2dcb8a..390f265a2 100644 --- a/features/steps/sign_in_steps.py +++ b/features/steps/sign_in_steps.py @@ -1,8 +1,6 @@ -from selenium.webdriver.common.by import By from behave import then -from selenium.webdriver.support import expected_conditions as EC @then('Verify Sign in page opened') def verify_sign_in_opened(context): - context.driver.wait.until(EC.url_contains('ap/signin'), message='Signin URL did not open') \ No newline at end of file + context.app.sign_in_page.verify_signin_opened() \ No newline at end of file diff --git a/features/tests/amazon_main.feature b/features/tests/amazon_main.feature index f6988bad9..3082a1f08 100644 --- a/features/tests/amazon_main.feature +++ b/features/tests/amazon_main.feature @@ -8,3 +8,8 @@ Feature: Tests for Amazon main page Scenario: Footer has correct amount of links Given Open amazon page Then Verify that footer has 38 links + + Scenario: User can see language options + Given Open Amazon page + When Hover over language options + Then Verify Spanish option present diff --git a/features/tests/amazon_search.feature b/features/tests/amazon_search.feature index fc02c76ab..655841dc0 100644 --- a/features/tests/amazon_search.feature +++ b/features/tests/amazon_search.feature @@ -5,7 +5,7 @@ Feature: Tests for amazon search Given Open amazon page When Search for coffee Then Search results for "coffee" are shown -# + # Scenario: User can search for mug # Given Open amazon page # When Search for mug @@ -20,7 +20,7 @@ Feature: Tests for amazon search |coffee |"coffee" | |mug |"mug" | |dress |"dress" | - |Tritan Farm to Table Pitcher on amazon |"Tritan Farm to Table Pitcher on amazon" | + |Tritan Farm to Table Pitcher on amazon |"Tritan Farm to Table Pitcher" | Scenario: User can add a product to the cart Given Open Amazon page @@ -30,4 +30,19 @@ Feature: Tests for amazon search And Click on Add to cart button And Open cart page Then Verify cart has 1 item(s) - And Verify cart has correct product \ No newline at end of file + And Verify cart has correct product + + Scenario: Verify that user can see product names and images + Given Open Amazon page + When Search for coffee + Then Verify that every product has a name and an image + + Scenario Outline: User can select and search in a department + Given Open Amazon page + When Select department by value + And Search for Faust + Then Verify department is selected + Examples: + |value |department | + |stripbooks |books | + |audible |audible | diff --git a/features/tests/sign_in.feature b/features/tests/sign_in.feature index 93bbd5304..b4132f4c4 100644 --- a/features/tests/sign_in.feature +++ b/features/tests/sign_in.feature @@ -5,3 +5,16 @@ Feature: Sign in test cases Given Open Amazon page When Click on button from SignIn popup Then Verify Sign in page opened + + Scenario: Amazon users see sign in button + Given Open Amazon page + Then Verify Sign In is clickable + When Wait for 3 sec + Then Verify Sign In is clickable + Then Verify Sign In disappears + + Scenario: Verify that logged out user sees Sign In when clicking on Returns and Orders + Given Open Amazon page + When Click Orders + Then Verify Sign in page opened + diff --git a/pages/base_page.py b/pages/base_page.py index ed2d2cb15..b3a45ae21 100644 --- a/pages/base_page.py +++ b/pages/base_page.py @@ -30,7 +30,7 @@ def input_text(self, text, *locator): print(f'Inputting text: {text}') def wait_for_element_click(self, *locator): - e = self.wait.until(EC.element_to_be_clickable(locator)) + e = self.wait.until(EC.element_to_be_clickable(locator), message=f'Element not clickable by {locator}') e.click() def wait_for_element_disappear(self, *locator): @@ -41,12 +41,13 @@ def wait_for_element_appear(self, *locator): def verify_element_text(self, expected_text, *locator): actual_text = self.driver.find_element(*locator).text - assert expected_text == actual_text, f'Expected {expected_text}, but got {actual_text}' + assert expected_text == actual_text, \ + f'Checking by locator {locator}. Expected {expected_text}, but got {actual_text}' def verify_partial_text(self, expected_text, *locator): actual_text = self.driver.find_element(*locator).text assert expected_text in actual_text, \ - f'Expected text {expected_text} is not in {actual_text}' + f'Checking by locator {locator}. Expected text {expected_text} is not in {actual_text}' def verify_url_contains_query(self, query): self.wait.until(EC.url_contains(query)) \ No newline at end of file diff --git a/pages/main_page.py b/pages/main_page.py index 7b94270b1..4e26888d3 100644 --- a/pages/main_page.py +++ b/pages/main_page.py @@ -1,10 +1,17 @@ from selenium.webdriver.common.by import By +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.support.ui import Select + from pages.base_page import Page class MainPage(Page): SEARCH_INPUT = (By.ID, 'twotabsearchtextbox') SEARCH_BTN = (By.ID, 'nav-search-submit-button') + ORDERS_BTN = (By.ID, 'nav-orders') + LANG_SELECTION = (By.CSS_SELECTOR, ".icp-nav-flag-us") + SPANISH_LANG = (By.CSS_SELECTOR, '#nav-flyout-icp [href="#switch-lang=es_US"]') + DEPARTMENT_SELECTION = (By.ID, 'searchDropdownBox') def open_main(self): self.open_url() @@ -13,3 +20,9 @@ def search_product(self, product): self.input_text(product, *self.SEARCH_INPUT) self.click(*self.SEARCH_BTN) + def click_returns_and_orders_btn(self): + self.click(*self.ORDERS_BTN) + + def verify_lang(self): + self.wait_for_element_appear(*self.SPANISH_LANG) + diff --git a/pages/search_results_page.py b/pages/search_results_page.py index 88c28a3a0..0bee59f5b 100644 --- a/pages/search_results_page.py +++ b/pages/search_results_page.py @@ -5,6 +5,19 @@ class SearchResultsPage(Page): SEARCH_RESULTS = (By.CSS_SELECTOR, '.a-color-state.a-text-bold') + SELECTED_DEPARTMENT = (By.CSS_SELECTOR, '#nav-subnav[data-category="{SUBSTR}"]') + + def get_department_locator(self, department: str): + # department = books + # [ By.CSS_SELECTOR , '#nav-subnav[data-category="books"]' + return [self.SELECTED_DEPARTMENT[0], self.SELECTED_DEPARTMENT[1].replace('{SUBSTR}', department)] def verify_search_results(self, expected_result): self.verify_element_text(expected_result, *self.SEARCH_RESULTS) + + def verify_department(self, department): + print('department => ', department) + department_locator = self.get_department_locator(department) + print(department_locator) + self.wait_for_element_appear(*department_locator) + diff --git a/pages/signin_page.py b/pages/signin_page.py new file mode 100644 index 000000000..fda5090da --- /dev/null +++ b/pages/signin_page.py @@ -0,0 +1,14 @@ +from selenium.webdriver.common.by import By + +from pages.base_page import Page + + +class SignInPage(Page): + SIGNIN_HEADER = (By.XPATH, "//h1[@class='a-spacing-small']") + EMAIL_FIELD = (By.ID, 'ap_email') + + def verify_signin_opened(self): + self.verify_element_text('Sign in', *self.SIGNIN_HEADER) + # Verify email field present + assert self.find_element(*self.EMAIL_FIELD).is_displayed() + # self.verify_url_contains_query('https://www.amazon.com/ap/signin')