Skip to content

Commit 58a6b0a

Browse files
committed
updated test scenerio
1 parent b201dde commit 58a6b0a

14 files changed

+209
-69
lines changed

app/application.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
from pages.main_page import MainPage
1+
from pages.base_page import Page
2+
from pages.cart_page import CartPage
23
from pages.header import Header
4+
from pages.main_page import MainPage
35
from pages.search_result_page import SearchResultsPage
6+
from pages.cart_page import CartPage
7+
from pages.sign_in_page import SignIn
48

59

610
class Application:
711

812
def __init__(self, driver):
9-
self.main_page = MainPage(driver)
13+
self.base_page = Page(driver)
14+
self.cart_page = CartPage(driver)
1015
self.header = Header(driver)
16+
self.main_page = MainPage(driver)
1117
self.search_result_page = SearchResultsPage(driver)
18+
self.sign_in_page = SignIn(driver)
19+
self.pages = Page(driver)
20+
1221

1322

1423

features/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ def before_step(context, step):
3636
def after_step(context, step):
3737
if step.status == 'failed':
3838
print('\nStep failed: ', step)
39+
context.app.base_page.save_screenshot('step')
3940

4041

4142
def after_scenario(context, feature):
42-
context.driver.delete_all_cookies()
4343
context.driver.quit()

features/steps/cart_page_steps.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from selenium.webdriver.common.by import By
2+
from behave import when, then
3+
4+
CART_SUMMARY = (By.CSS_SELECTOR, "[class*='CartSummarySpan']")
5+
CART_ITEM_TITLE = (By.CSS_SELECTOR, "[data-test='cartItem-title']")
6+
7+
8+
@when('Open cart page')
9+
def open_cart(context):
10+
context.driver.get('https://www.target.com/cart')
11+
12+
13+
@then('Verify cart has correct product')
14+
def verify_product_name(context):
15+
actual_name = context.driver.find_element(*CART_ITEM_TITLE).text
16+
assert context.product_name in actual_name, f"Expected {context.product_name} but got {actual_name}"
17+
18+
19+
@then('Verify cart has {amount} item(s)')
20+
def verify_cart_items(context, amount):
21+
cart_summary = context.driver.find_element(*CART_SUMMARY).text
22+
assert amount in cart_summary, f"Expected {amount} items but got {cart_summary}"
23+
24+
25+
@then("Verify 'Your cart is empty' message is shown")
26+
def verify_cart_empty_message(context):
27+
context.app.cart_page.verify_cart_empty_message()

features/steps/main_page_steps.py

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,25 @@
11
from selenium.webdriver.common.by import By
2-
from selenium.webdriver.support import expected_conditions as EC
32
from behave import given, when, then
43
from time import sleep
5-
6-
7-
SEARCH_INPUT = (By.ID, 'search')
8-
SEARCH_BTN = (By.XPATH, "//button[@data-test='@web/Search/SearchButton']")
9-
CART_ICON = (By.CSS_SELECTOR, "[data-test='@web/CartLink']")
10-
HEADER = (By.CSS_SELECTOR, "[class*='UtilityHeaderWrapper']")
11-
HEADER_LINKS = (By.CSS_SELECTOR, "a[id*='utilityNav']")
12-
ADD_TO_CART_BTN = (By.CSS_SELECTOR, "[id*='addToCartButton']")
13-
SIDE_NAV_PRODUCT_NAME = (By.CSS_SELECTOR, "h4[class*='StyledHeading']")
14-
SIDE_NAV_ADD_TO_CART_BTN = (By.CSS_SELECTOR, "[data-test='orderPickupButton']")
4+
from pages import sign_in_page
155

166

177
@given('Open Target main page')
188
def open_target(context):
199
context.app.main_page.open_main()
2010

2111

22-
@when("Search for {item}")
23-
def search_product(context, item):
24-
context.app.header.search_product(item)
25-
26-
27-
@when('Click on Cart icon')
28-
def click_cart(context):
29-
context.driver.find_element(*CART_ICON).click()
30-
31-
32-
@when('Click on Add to Cart button')
33-
def click_add_to_cart(context):
34-
context.driver.find_element(*ADD_TO_CART_BTN).click()
35-
# Add multiple:
36-
# add_cart_btns = context.driver.find_elements(*ADD_TO_CART_BTN)
37-
# for btn in add_cart_btns[:5]:
38-
# btn.click() # => will click on the first 5 buttons 1 by 1
39-
# add_cart_btns[4].click() # => will only click on the 5th Add to cart btn
40-
41-
42-
@when('Store product name')
43-
def store_product_name(context):
44-
context.wait.until(
45-
EC.presence_of_element_located(SIDE_NAV_PRODUCT_NAME),
46-
message='Product name not present on the page'
47-
)
48-
context.product_name = context.driver.find_element(*SIDE_NAV_PRODUCT_NAME).text
49-
50-
51-
@when('Confirm Add to Cart button from side navigation')
52-
def side_nav_click_add_to_cart(context):
53-
context.driver.find_element(*SIDE_NAV_ADD_TO_CART_BTN).click()
54-
context.wait.until(
55-
EC.invisibility_of_element_located(SIDE_NAV_ADD_TO_CART_BTN),
56-
message='Side nav, Add to Cart button did not disappear'
57-
)
12+
@when("Click Sign in")
13+
def click_sign_in(context):
14+
context.app.sign_in_page.click_sign_in()
5815

5916

60-
@then('Verify header in shown')
61-
def verify_header_shown(context):
62-
context.driver.find_element(*HEADER)
17+
@then('From side nav menu, click Sign in')
18+
def side_nav_sign_in_btn(context):
19+
context.app.sign_in_page.side_nav_sign_in_btn()
6320

6421

65-
@then('Verify header has {expected_amount} links')
66-
def verify_header_links(context, expected_amount): # expected_amount = '5'
67-
expected_amount = int(expected_amount) # '5' (str) => 5 (int)
68-
links = context.driver.find_elements(*HEADER_LINKS)
69-
assert len(links) == expected_amount, f'Expected {expected_amount} links but got {len(links)}'
22+
@then('Verify Sign in form opened')
23+
def verify_sign_in_shown(context):
24+
context.app.base_page.verify_sign_in_shown('Sign into your Target account')
25+
sleep(8)

features/steps/search_results_page_steps.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from selenium.webdriver.common.by import By
2+
from selenium.webdriver.support import expected_conditions as EC
3+
24
from behave import then
35
from time import sleep
46

57

8+
69
SEARCH_RESULT_HEADER = (By.XPATH, "//div[@data-test='resultsHeading']")
710
LISTINGS = (By.CSS_SELECTOR, "[data-test='@web/site-top-of-funnel/ProductCardWrapper']")
811
PRODUCT_TITLE = (By.CSS_SELECTOR, "[data-test='product-title']")
@@ -14,6 +17,11 @@ def verify_search_results(context, expected_item):
1417
context.app.search_result_page.verify_search_results(expected_item)
1518

1619

20+
@then('Verify that URL has {partial_url}')
21+
def verify_search_page_url(context, partial_url):
22+
context.app.search_result_page.verify_partial_url(partial_url)
23+
24+
1725
@then('Verify that every product has a name and an image')
1826
def verify_products_name_img(context):
1927
# To see ALL listings (comment out if you only check top ones):

features/tests/cart_tests.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ Feature: Cart tests
1313
And Confirm Add to Cart button from side navigation
1414
And Open cart page
1515
Then Verify cart has 1 item(s)
16-
And Verify cart has correct product
16+
And Verify cart has correct product

features/tests/sign_in_test.feature

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Feature: Target Sign In
2+
3+
Scenario: Logged out user can Sign in
4+
Given Open Target main page
5+
When Click Sign in
6+
Then From side nav menu, click Sign in
7+
And Verify Sign in form opened

features/tests/target_search.feature

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ Feature: Search tests
33

44
Scenario: User can search for a tea
55
Given Open Target main page
6-
When Search for ice tea
7-
Then Verify search results are shown for ice tea
6+
When Search for icetea
7+
Then Verify search results are shown for icetea
8+
Then Verify that URL has icetea
89

910
Scenario Outline: User can search for a product
1011
Given Open Target main page
@@ -15,8 +16,3 @@ Feature: Search tests
1516
|mug |mug |
1617
|tea |tea |
1718
|white mug |white mug |
18-
19-
Scenario: Verify that user can see product names and images
20-
Given Open target main page
21-
When Search for AirPods (3rd Generation)
22-
Then Verify that every product has a name and an image

pages/base_page.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
from selenium.webdriver.common.by import By
2+
from selenium.webdriver.support.wait import WebDriverWait
3+
from selenium.webdriver.support import expected_conditions as EC
4+
15

26
class Page:
37

48
def __init__(self, driver):
59
self.driver = driver
10+
self.wait = WebDriverWait(self.driver, 10)
611

712
def find_element(self, *locator):
813
return self.driver.find_element(*locator)
@@ -14,4 +19,65 @@ def click(self, *locator):
1419
self.find_element(*locator).click()
1520

1621
def input_text(self, text, *locator):
17-
self.find_element(*locator).send_keys(text)
22+
self.find_element(*locator).send_keys(text)
23+
24+
def wait_until_clickable(self, *locator):
25+
self.wait.until(
26+
EC.element_to_be_clickable(locator),
27+
message=f'Element not clickable by {locator}'
28+
).click()
29+
30+
def wait_until_visible(self, *locator):
31+
self.wait.until(
32+
EC.visibility_of_element_located(locator),
33+
f'Element not visible by {locator}'
34+
)
35+
36+
def wait_until_disappears(self, *locator):
37+
self.wait.until(
38+
EC.invisibility_of_element_located(locator),
39+
f'Element still visible by {locator}'
40+
)
41+
42+
def get_current_window(self):
43+
current_window = self.driver.current_window_handle
44+
print('Current:', current_window)
45+
print('ALL windows:', self.driver.window_handles)
46+
return current_window
47+
48+
def switch_to_new_window(self):
49+
self.wait.until(EC.new_window_is_opened)
50+
all_windows = self.driver.window_handles # [Win1, Win2, ...]
51+
print('ALL windows:', self.driver.window_handles)
52+
print('Switching to... ', all_windows[1])
53+
self.driver.switch_to.window(all_windows[1])
54+
55+
def switch_window_by_id(self, window_id):
56+
print('Switching to... ', window_id)
57+
self.driver.switch_to.window(window_id)
58+
59+
def verify_partial_text(self, expected_text, *locator):
60+
actual_text = self.find_element(*locator).text
61+
assert expected_text in actual_text, f'Expected {expected_text}, not in {actual_text}'
62+
63+
def verify_partial_url(self, expected_partial_url):
64+
self.wait.until(EC.url_contains(expected_partial_url), message=f'Url doest not contain {expected_partial_url}')
65+
66+
def verify_url(self, expected_url):
67+
self.wait.until(EC.url_matches(expected_url), message=f'Url does not contain {expected_url}')
68+
69+
def save_screenshot(self, name):
70+
self.driver.save_screenshot(f'{name}.png')
71+
72+
def close(self):
73+
self.driver.close()
74+
75+
def click_sign_in(self, *locator):
76+
self.find_element(*locator).click()
77+
78+
def side_nav_sign_in_btn(self, *locator):
79+
self.find_element(*locator).click()
80+
81+
def verify_sign_in_shown(self, expected_text, *locator):
82+
actual_text = self.find_element(*locator).text
83+
assert expected_text == expected_text, f'Expected {expected_text} but got {actual_text}'

pages/cart_page.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from selenium.webdriver.common.by import By
2+
3+
from pages.base_page import Page
4+
5+
6+
class CartPage(Page):
7+
CART_EMPTY_MSG = (By.CSS_SELECTOR, "h1[class*='StyledHeading']")
8+
9+
def verify_cart_empty_message(self):
10+
self.verify_text('Your cart is empty', *self.CART_EMPTY_MSG)

pages/header.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
class Header(Page):
88
SEARCH_INPUT = (By.ID, 'search')
99
SEARCH_BTN = (By.XPATH, "//button[@data-test='@web/Search/SearchButton']")
10+
CART_ICON = (By.CSS_SELECTOR, "[data-test='@web/CartLink']")
1011

1112
def search_product(self, item):
1213
self.input_text(item, *self.SEARCH_INPUT)
1314
self.click(*self.SEARCH_BTN)
14-
sleep(6)
15+
sleep(6)
16+
17+
def click_cart(self):
18+
self.wait_until_clickable(*self.CART_ICON)
19+
self.save_screenshot('cart.png')

pages/main_page.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
class MainPage(Page):
55

66
def open_main(self):
7-
self.driver.get('https://www.target.com/')
7+
self.driver.get('https://www.target.com/')
8+

pages/sign_in_page.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from selenium.webdriver.common.by import By
2+
3+
from pages.base_page import Page
4+
from behave import when, then
5+
6+
7+
class SignIn(Page):
8+
SIGNIN_BTN = (By.CSS_SELECTOR, "a[data-test='@web/AccountLink']")
9+
SIDE_NAV_BTN = (By.CSS_SELECTOR, "a[data-test='accountNav-signIn']")
10+
VERIFY_SIGNIN_OPEN = (By.CSS_SELECTOR, "h1[class*='StyledHeading']")
11+
12+
def click_sign_in(self):
13+
self.click(*self.SIGNIN_BTN)
14+
15+
def side_nav_sign_in_btn(self):
16+
self.wait_until_clickable(*self.SIDE_NAV_BTN)
17+
18+
def verify_sign_in_shown(self, expected_text, *locator):
19+
self.verify_sign_in_shown(*self.VERIFY_SIGNIN_OPEN)

pages/target_app_page_steps.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from behave import given, when, then
2+
3+
4+
@given('Open Target App page')
5+
def open_target_app(context):
6+
context.app.target_app_page.open_target_app()
7+
8+
9+
@given('Store original window')
10+
def store_original_window(context):
11+
context.original_window = context.app.target_app_page.get_current_window()
12+
13+
14+
@when('Click Privacy Policy link')
15+
def click_pp_link(context):
16+
context.app.target_app_page.click_pp_link()
17+
18+
19+
@when('Switch to new window')
20+
def switch_window(context):
21+
context.app.target_app_page.switch_to_new_window()
22+
23+
24+
@then('Verify Privacy Policy page opened')
25+
def verify_pp_opened(context):
26+
context.app.target_app_page.verify_pp_opened()
27+
28+
29+
@then('Close current page')
30+
def close(context):
31+
context.app.target_app_page.close()
32+
33+
34+
@then('Return to original window')
35+
def return_to_original_window(context):
36+
context.app.target_app_page.switch_window_by_id(context.original_window)

0 commit comments

Comments
 (0)