diff --git a/Amazon Sign In Test b/Amazon Sign In Test new file mode 100644 index 000000000..57af39cb3 --- /dev/null +++ b/Amazon Sign In Test @@ -0,0 +1,21 @@ +from sample_script import driver +# Amazon logo +driver.find_element(By.XPATH, "//*[@aria-label='Amazon']") + +#Email field +driver.find_element(By.XPATH, "//input[@class='a-input-text']") + +# Continue button, By ID +driver.find_element(By.ID, 'continue-announce') + +# Conditions of use link +driver.find_element(By.XPATH, "//a[text()= 'Conditions of Use']") + +# Privacy Notice link +driver.find_element(By.XPATH, "//a[text()= 'Privacy Notice']") + +# Need help link +driver.find_element(By.XPATH, "//a[@class='a-size-base a-link-normal']") + +# Create a free business account +driver.find_element(By.XPATH, "//a[@class='a-link-normal']") diff --git a/Amazon Sign In Test.py b/Amazon Sign In Test.py new file mode 100644 index 000000000..016c529e0 --- /dev/null +++ b/Amazon Sign In Test.py @@ -0,0 +1,27 @@ +from sample_script import driver +from selenium.webdriver.common.by import By + +# Amazon logo +driver.find_element(By.XPATH, "//*[@aria-label='Amazon']") + +#Email field +driver.find_element(By.XPATH, "//input[@class='a-input-text']") + +# Continue button, By ID +driver.find_element(By.ID, 'continue-announce') + +# Conditions of use link +driver.find_element(By.XPATH, "//a[text()= 'Conditions of Use']") + +# Privacy Notice link +driver.find_element(By.XPATH, "//a[text()= 'Privacy Notice']") + +# Need help link +driver.find_element(By.XPATH, "//a[@class='a-size-base a-link-normal']") + +# Create a free business account +driver.find_element(By.XPATH, "//a[@class='a-link-normal']") + + + + diff --git a/Stack Overflow Test.py b/Stack Overflow Test.py new file mode 100644 index 000000000..b41c9fda0 --- /dev/null +++ b/Stack Overflow Test.py @@ -0,0 +1,23 @@ +# Create your account +driver.find_element(By.XPATH, "//h1[@class='flex--item fs-headline1 fw-bold lh-xs mb8 ws-nowrap']") + +# 'Terms of service' paragraph +driver.find_element(By.XPATH, "//div[@class='flex--item js-terms fs-caption fc-black-400 ta-left']") + +# Email +driver.find_element(By.ID, "email") + +# Password +driver.find_element(By.ID, "password") + +# Sign- Up Button +driver.find_element(By.ID, "submit-button") + +# Sign-up w/ button +diver.find_element(By.XPATH, "//button[@data-provider='google']") + +# Sign -up w/ GitHub +driver.find_element(By.XPATH, "//button[@data-provider='github']") + +# Get Stack Overflow for Teams +driver.find_element(By.XPATH, "//a[text()='Get Stack Overflow Internal free for up to 50 users']") diff --git a/Target Test w/Target Sign-In.py b/Target Test w/Target Sign-In.py new file mode 100644 index 000000000..4773eb1f0 --- /dev/null +++ b/Target Test w/Target Sign-In.py @@ -0,0 +1,19 @@ +from selenium import webdriver +from time import sleep + +from selenium.webdriver.common.by import By + +driver = webdriver.Chrome() +driver.maximize_window() + +# open the url +driver.get('https://www.target.com/') + +# sign In +driver.find_element(By.XPATH, "//span[text()='Account']").click() +driver.find_element(By.XPATH, "//button[@data-test='accountNav-signIn']").click() + +# verify +expected = 'Sign in or create account' +actual = driver.find_element(By.XPATH, "//h1[text()='Sign in or create account']").text +assert expected == actual, f'Expected {expected} did not match actual {actual}' \ No newline at end of file diff --git a/Target Test.py b/Target Test.py new file mode 100644 index 000000000..a9ead82b5 --- /dev/null +++ b/Target Test.py @@ -0,0 +1,31 @@ +from selenium import webdriver +from time import sleep + +from selenium.webdriver.common.by import By + +driver = webdriver.Chrome() +driver.maximize_window() +driver.implicitly_wait(5) + +# open the url +driver.get('https://www.target.com/') + +# Click Account Button +driver.find_element(By.XPATH, "//a[@data-test='@web/AccountLink']").click() +driver.find_element(By.XPATH, "//*[text()='Account']").click() +driver.find_element(By.XPATH, "//button[@data-test='accountNav-signIn']").click() + +# Verify Sign-in page open +expected_text = 'Sign in or create account' +actual_text = driver.find_element(By.XPATH,"//*[text()='Sign in or create account']") +assert expected_text == actual_text, f'Expect text{expected_text} did not match actual text {actual_text}' + +# Make sure login button is shown +driver.find_element(By.ID, 'login') + + +driver.quit() + + + +# \ No newline at end of file diff --git a/app/application.py b/app/application.py new file mode 100644 index 000000000..6930d9a74 --- /dev/null +++ b/app/application.py @@ -0,0 +1,14 @@ +from pages.base_page import Page +from pages.cart_page import Cart_Page +from pages.header import Header +from pages.main_page import MainPage +from pages.search_results_page import SearchResultsPage + + +class Application: + def __init__(self, driver): + self.cart_page = Cart_Page(driver) + self.header = Header(driver) + self.main_page = MainPage(driver) + self.page = Page(driver) + self.search_results_page = SearchResultsPage(driver) \ No newline at end of file diff --git a/features/environment.py b/features/environment.py index 1275460a0..35516d9d0 100755 --- a/features/environment.py +++ b/features/environment.py @@ -1,6 +1,11 @@ from selenium import webdriver from selenium.webdriver.chrome.service import Service +from selenium.webdriver.support.wait import WebDriverWait from webdriver_manager.chrome import ChromeDriverManager +from selenium.webdriver.support import expected_conditions as EC + + +from app.application import Application def browser_init(context): @@ -13,7 +18,8 @@ def browser_init(context): context.driver.maximize_window() context.driver.implicitly_wait(4) - + context.driver.wait = WebDriverWait(context.driver, timeout=10) + context.app = Application(context.driver) def before_scenario(context, scenario): print('\nStarted scenario: ', scenario.name) diff --git a/features/steps/add_to_target_cart_steps.py b/features/steps/add_to_target_cart_steps.py new file mode 100644 index 000000000..e893e8b51 --- /dev/null +++ b/features/steps/add_to_target_cart_steps.py @@ -0,0 +1,22 @@ +from time import sleep + +from selenium.webdriver.common.by import By +from behave import given, when, then +from selenium.webdriver.support.wait import WebDriverWait +from selenium. webdriver.support import expected_conditions as EC + +@when('Click on add to cart button') +def click_add_to_cart(context): + sleep(20) + context.driver.find_element(By.CSS_SELECTOR, "[data-test='chooseOptionsButton']").click() + sleep(5) + context.driver.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[aria-label="Fulfillment"] [id*="addToCartButtonOrTextIdFor"]'))).click() + + +@then('Confirm added to cart message from side navigation') +def added_to_cart_message_from_side_navigation(context): + sleep(5) + actual_text = context.driver.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'h2[data-test="modal-drawer-heading"] span[class="h-text-lg"]'))).text + + expected_text = 'Added to cart' + assert actual_text==expected_text, f'Expected text to be {expected_text}, but got {actual_text}' diff --git a/features/steps/header_steps.py b/features/steps/header_steps.py new file mode 100644 index 000000000..ea549d5d5 --- /dev/null +++ b/features/steps/header_steps.py @@ -0,0 +1,28 @@ +from selenium.webdriver.common.by import By +from behave import given, when, then + + + + + +@when('Search for {product}') +def search_for_product(context, product): + context.app.header.search(product) + #context.driver.find_element(By.ID, 'search').send_keys(product) + #context.driver.find_element(By.CSS_SELECTOR, '[data-test="@web/Search/SearchButton"]').click() + + +@when('Click on account button') +def click_on_account_button(context): + context.driver.find_element(By.CSS_SELECTOR, '[aria-label="Account, sign in"]').click() + + +@when('Open target circle') +def open_target_circle(context): + context.driver.find_element(By.ID, 'utilityNav-circle').click() + + +@when('Click on Cart Icon') +def click_on_cart_icon(context): + #context.driver.find_element(By.XPATH, '//a[@data-test="@web/CartLink"]').click() + context.app.header.click_on_cart_icon() \ No newline at end of file diff --git a/features/steps/main_page_steps.py b/features/steps/main_page_steps.py new file mode 100644 index 000000000..4c0f6c92a --- /dev/null +++ b/features/steps/main_page_steps.py @@ -0,0 +1,8 @@ +from selenium.webdriver.common.by import By +from behave import given, when, then + + +@given("Open target main page") +def open_target_main_page(context): + context.driver.get('https://www.target.com/') + diff --git a/features/steps/seach_results_page_steps.py b/features/steps/seach_results_page_steps.py new file mode 100644 index 000000000..6f63f2a13 --- /dev/null +++ b/features/steps/seach_results_page_steps.py @@ -0,0 +1,17 @@ +from selenium.webdriver.common.by import By +from behave import given, when, then + + + + + +@then('Search results for cart button') +def search_results_for_cart(context): + context.app.search_results_page.verify_search_results() + + + + + + + diff --git a/features/steps/target_cart_steps.py b/features/steps/target_cart_steps.py new file mode 100644 index 000000000..76921fdd7 --- /dev/null +++ b/features/steps/target_cart_steps.py @@ -0,0 +1,29 @@ +from selenium.webdriver.common.by import By +from behave import given, when, then + + +@when('Click on Cart Icon') +def click_on_cart_icon(context): + context.driver.find_element(By.XPATH, '//a[@data-test="@web/CartLink"]').click() + + +@then('"Your cart is empty" message is shown') +def verify_empty_cart_message(context): + actual_text = context.driver.find_element(By.XPATH, "//h1[contains(@class, styles_ndsHeading)]").text + assert 'Your cart is empty' in actual_text, f"Expected 'Your cart is empty' text not in {actual_text}" + + +@when('Click on Sign In or Create Account button') +def sign_in_or_create_account_button(context): + context.driver.find_element(By.XPATH, "//button[@data-test='accountNav-signIn']").click() + + +@then('"Sign in or create account" page is shown') +def verify_sign_in_message(context): + actual_text = context.driver.find_element(By.XPATH,"//*[text()='Sign in or create account']") + assert "Sign in or create account" in actual_text, f"Expected 'Sign in or create account' text not in {actual_text}" + + + + + diff --git a/features/steps/target_circle_page_steps.py b/features/steps/target_circle_page_steps.py new file mode 100644 index 000000000..41a644d73 --- /dev/null +++ b/features/steps/target_circle_page_steps.py @@ -0,0 +1,36 @@ +from selenium.webdriver.common.by import By +from behave import given, when, then + + + # find benefits cells +@when('Click for benefit cells') +def verify_benefits_cells(context): + context.driver.find_element(By.XPATH, "//button[@data-test='storycard--staticButton']").click() + + +@then('Sign in or create account page') +def sign_in_or_create_account_page(context): + actual_text = context.driver.find_element(By.XPATH, "//h1[contains(text(),'Sign in or create account')]").text + assert 'Sign in or create account' in actual_text, f"Expected 'Sign in or create account' text not in {actual_text}" + + +@when('Click for pharmacy') +def click_pharmacy(context): + context.driver.find_element(By.CSS_SELECTOR, '[aria-label="Pharmacy"]').click() + + +@then('CVS Pharmacy & Vaccines page') +def CVS_Pharmacy_Vaccines_page(context): + actual_text = context.driver.find_element(By.XPATH, "//h1[contains(text(), 'CVS Pharmacy & Vaccines')]").text + assert 'CVS Pharmacy & Vaccines' in actual_text, f"Expected 'CVS Pharmacy & Vaccines' text not in {actual_text}" + + +@when('Click for target help') +def verify_help(context): + context.driver.find_element(By.CSS_SELECTOR, '[aria-label="Target Help"]').click() + + +@then('Verify the help page opens') +def verify_help_page_opens(context): + actual_text = context.driver.find_element(By.CSS_SELECTOR, "[aria-current='page']").text + assert 'Help' in actual_text, f"Expected 'Help' text not in {actual_text}" \ No newline at end of file diff --git a/features/steps/target_product_colors_steps.py b/features/steps/target_product_colors_steps.py new file mode 100644 index 000000000..30d0d8e2f --- /dev/null +++ b/features/steps/target_product_colors_steps.py @@ -0,0 +1,38 @@ +from behave import then, given +from selenium.webdriver.common.by import By +from time import sleep + + + +@given('Open target product A-94089062 page') +def open_target(context): + context.driver.get('https://www.target.com/p/josmo-boys-slip-on-casual-boat-style-shoes-little-kids-toddler-tan-size-10/-/A-94089062') + sleep(5) + + +@then('Verify that every product color is clicked and correct') +def verify_product_color_is_clicked_correct(context): + expected_colors = ['black', 'tan'] + actual_colors = [] + + + COLOR_CHOICES = (By.CSS_SELECTOR, 'a[class*="styles_ndsBaseButton"] img[class*="styles_pictureLazy"]') + SELECTED_COLOR = (By.CSS_SELECTOR, '[data-test="@web/VariationComponent"] div[class*="styles_headerWrapper"]') + + colors = context.driver.find_elements(*COLOR_CHOICES) + print(colors) + + + for color in colors: + color.click() + sleep(10) + + selected_color = context.driver.find_elements(*SELECTED_COLOR)[1].text + + selected_color = selected_color.split('\n')[1] + actual_colors.append(selected_color) + + assert expected_colors == actual_colors, f"Expected colors are: ({expected_colors}), but got Actual colors: ({actual_colors}) " + + + diff --git a/features/steps/update_target_product_search_steps.py b/features/steps/update_target_product_search_steps.py new file mode 100644 index 000000000..769e47e8e --- /dev/null +++ b/features/steps/update_target_product_search_steps.py @@ -0,0 +1,8 @@ +from selenium.webdriver.common.by import By +from behave import given, when, then + + +@then('Search results for product are shown') +def verify_product_results_shown(context): + actual_text = context.driver.find_element(By.CSS_SELECTOR, 'div[data-module-type="ListingPageResultsCount"] h2').text + assert 'results' in actual_text, f"Expected 'results' text not in {actual_text}" \ No newline at end of file diff --git a/features/tests/add_to_target_cart.feature b/features/tests/add_to_target_cart.feature new file mode 100644 index 000000000..7a133ae1c --- /dev/null +++ b/features/tests/add_to_target_cart.feature @@ -0,0 +1,11 @@ +# created by rollyn + +Feature: User can add any product to cart + + Scenario: User can add product to cart + Given Open target main page + When Search for tea + And Click on add to cart button + Then Confirm added to cart message from side navigation + + diff --git a/features/tests/cart_page.feature b/features/tests/cart_page.feature new file mode 100644 index 000000000..48f60b19b --- /dev/null +++ b/features/tests/cart_page.feature @@ -0,0 +1,7 @@ +# created by rollyn + Feature: Rewrite this scenario with Page Object pattern: + + Scenario: "Your cart is empty" message is shown for empty cart + Given Open target main page + When Click on Cart Icon + Then "Your cart is empty" message is shown \ No newline at end of file diff --git a/features/tests/target_cart_feature.feature b/features/tests/target_cart_feature.feature new file mode 100644 index 000000000..b1cfe9cfe --- /dev/null +++ b/features/tests/target_cart_feature.feature @@ -0,0 +1,14 @@ +# created by rollyn +Feature: Test Scenarios for Target's Cart and Sign In Button functionality + + Scenario: User can use Target cart buttons + Given Open target main page + When Click on Cart Icon + Then "Your cart is empty" message is shown + + + Scenario: User can navigate to "sign In" + Given Open target main page + When Click on account button + And Click on Sign In or Create Account button + Then "Sign in or create account" page is shown \ No newline at end of file diff --git a/features/tests/target_circle_page.feature b/features/tests/target_circle_page.feature new file mode 100644 index 000000000..48ea262c0 --- /dev/null +++ b/features/tests/target_circle_page.feature @@ -0,0 +1,21 @@ +# created by rollyn +Feature: Test Scenarios for Target's Circle functionality + + Scenario: User can use benefit cells + Given Open target main page + When Open target circle + And Click for benefit cells + Then Sign in or create account page + + Scenario: User can use the pharmacy button + Given Open target main page + When Open target circle + And Click for pharmacy + Then CVS Pharmacy & Vaccines page + + + Scenario: User can use the target help button + Given Open target main page + When Open target circle + And Click for target help + Then Verify the help page opens \ No newline at end of file diff --git a/features/tests/target_product_colors.feature b/features/tests/target_product_colors.feature new file mode 100644 index 000000000..84fd2611e --- /dev/null +++ b/features/tests/target_product_colors.feature @@ -0,0 +1,10 @@ +# created by rollyn +#from behave.model import Scenario + +Feature: Test Scenarios for Target's products name and images + + +Scenario: Verify user can see product name and images + Given Open target product A-94089062 page + Then Verify that every product color is clicked and correct + diff --git a/features/tests/update_target_product_search.feature b/features/tests/update_target_product_search.feature new file mode 100644 index 000000000..ea17544b1 --- /dev/null +++ b/features/tests/update_target_product_search.feature @@ -0,0 +1,11 @@ +# created by rollyn + +Feature: Update Target product search + + Scenario: User can search for product + Given Open target main page + When Search for product + Then Search results for product are shown + + + # assert isinstance(context.driver.find_element(By.XPATH, "//button[@data-test='storycard--staticButton']")) diff --git a/locaors.py b/locaors.py new file mode 100644 index 000000000..d0fa2b0e1 --- /dev/null +++ b/locaors.py @@ -0,0 +1,30 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.chrome.service import Service +from webdriver_manager.chrome import ChromeDriverManager +from time import sleep + +# get the path to the ChromeDriver executable +driver_path = ChromeDriverManager().install() + +# create a new Chrome browser instance +service = Service(driver_path) +driver = webdriver.Chrome(service=service) +driver.maximize_window() + +# open the url +driver.get('https://www.amazon.com/') + +# Locators +# By ID +driver.find_element(By.ID, 'twotabsearchtextbox') +driver.find_element(By.ID, 'searchDropdownBox') + +driver.find_element(By.XPATH, "//input[@aria-label='Search Amazon']") +driver.find_element(By.XPATH, "//input[@class='nav-input nav-progressive-attribute']") + +# By attributes, any tag +driver.find_element(By.XPATH, "//*[@placeholder='Search Amazon']") + +driver.find_element(By.XPATH, "//input[@class='nav-input nav-progressive-attribute' and @type='text']") +driver.find_element(By.XPATH, "//input[@class='nav-input nav-progressive-attribute']") \ No newline at end of file diff --git a/pages/base_page.py b/pages/base_page.py new file mode 100644 index 000000000..498af9d42 --- /dev/null +++ b/pages/base_page.py @@ -0,0 +1,43 @@ +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + + +class Page: + def __init__(self,driver): + self.driver = driver + self.wait = WebDriverWait(driver,10) + + + def open_url(self,url): + self.driver.get(url) + + def find_element(self,*locator): + return self.driver.find_element(*locator) + + def find_elements(self,*locator): + return self.driver.find_elements(*locator) + + def click(self, *locator): + self.driver.find_element(*locator).click() + + + def input_text(self, text, *locator): + self.driver.find_element(*locator).send_keys(text) + + def wait_until_present(self, locator): + self.wait.until( + EC.presence_of_element_located(locator), + message=f"Element {locator} was not present." + ) + + def wait_until_clickable(self, locator): + self.wait.until( + EC.element_to_be_clickable(locator), + message=f"Element {locator} was not present." + ) + + def wait_until_clickable_click(self, locator): + self.wait.until( + EC.element_to_be_clickable(locator), + message=f"Element {locator} was not present." + ).click() diff --git a/pages/cart_page.py b/pages/cart_page.py new file mode 100644 index 000000000..261c5c4c1 --- /dev/null +++ b/pages/cart_page.py @@ -0,0 +1,13 @@ +from selenium.webdriver.common.by import By + +from pages.base_page import Page + + +class Cart_Page(Page): + EMPTY_CART_MESSAGE = (By.XPATH, "//h1[contains(@class, styles_ndsHeading)]") + + def verify_empty_cart_message(self): + actual_text = self.find_element(*self.EMPTY_CART_MESSAGE).text + assert 'Your cart is empty' in actual_text, f"Expected 'Your cart is empty' text not in {actual_text}" + + diff --git a/pages/header.py b/pages/header.py new file mode 100644 index 000000000..bc7b35ac1 --- /dev/null +++ b/pages/header.py @@ -0,0 +1,19 @@ +from selenium.webdriver.common.by import By +from time import sleep +from pages.base_page import Page + + +class Header(Page): + CART_ICON = (By.CSS_SELECTOR, '[data-test="@web/CartIcon"]') + SEARCH_FIELD = (By.ID, 'search') + SEARCH_ICON = (By.CSS_SELECTOR, '[data-test="@web/Search/SearchButton"]') + + + def search(self, product): + self.input_text(product, *self.SEARCH_FIELD) + self.click(*self.SEARCH_ICON) + sleep(10) + + + def click_on_cart_icon(self): + self.click(*self.CART_ICON) \ No newline at end of file diff --git a/pages/main_page.py b/pages/main_page.py new file mode 100644 index 000000000..2f239c174 --- /dev/null +++ b/pages/main_page.py @@ -0,0 +1,13 @@ +from pages.base_page import Page +from selenium.webdriver.common.by import By + + +class MainPage(Page): + def open_main_page(self): + context.app.main_page.open_main_page() + + context.driver.find_element(By.ID, 'search').send_keys(product) + context.driver.find_element(By.CSS_SELECTOR, '[data-test="@web/Search/SearchButton"]').click() + + + diff --git a/pages/search_results_page.py b/pages/search_results_page.py new file mode 100644 index 000000000..86076e190 --- /dev/null +++ b/pages/search_results_page.py @@ -0,0 +1,17 @@ +from selenium.webdriver.common.by import By +from time import sleep +from pages.base_page import Page + + +class SearchResultsPage(Page): + search_word = (By.CSS_SELECTOR, '[data-test="@web/Search/SearchButton"]') + ADD_TO_CART_SECOND = (By.CSS_SELECTOR, '[data-test="@web/AddToCart/Fulfillment/ShippingSection"] button[id*="addToCartButton"]') + + def verify_search_result(self): + actual_text = self.find_element(*self.search_word).text #from pro_sear.py + assert 'tea' in actual_text, f'Expected text "tea" not in actual text {actual_text}' + + def click_add_to_cart(self): + sleep(20) + self.find_element(By.CSS_SELECTOR, "[data-test='chooseOptionsButton']").click() + self.wait_until_clickable_click(self.ADD_TO_CART_SECOND)