Adds SFRA 6.0

This commit is contained in:
Isaac Vallee
2021-12-21 10:57:31 -08:00
parent d04eb5dd16
commit 823c7608c3
1257 changed files with 137087 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
{
"parserOptions": {
"ecmaVersion": 2017
},
"rules": {
"require-jsdoc": "off",
"max-len": "off",
"quote-props": "off",
"no-new": "off",
"valid-jsdoc": "off",
"no-undef": "off",
"new-cap": "off"
}
}

View File

@@ -0,0 +1,8 @@
Feature: Add Address to User Account
As a shopper with an account, I want to be able to add a saved address
@accountPage
Scenario: Shopper is able to add an address to their account
Given shopper logs into the website
And shopper clicks add new address
And shopper fills out address information

View File

@@ -0,0 +1,10 @@
Feature: Add Payment to User Account
As a shopper with an account, I want to be able to add a saved payment
@accountPage
Scenario: Shopper is able to add a payment to their account
Given shopper logs into the website
And shopper clicks add new payment
And shopper fills out their payment information
Then shopper clicks view payments
And shopper removes a saved credit card

View File

@@ -0,0 +1,8 @@
Feature: Edit password of a User Account
As a shopper with an account, I want to be able to change my password
@accountPage
Scenario: Shopper is able to change their password
Given shopper logs into the website
And shopper clicks edit password
And shopper changes their password

View File

@@ -0,0 +1,10 @@
Feature: Edit profile of a User Account
As a shopper with an account, I want to be able to edit my profile
Background:
Given shopper logs into the website
@accountPage @editProfile
Scenario: Shopper is able to edit their account information
Then shopper clicks edit profile
And shopper edits phone number

View File

@@ -0,0 +1,15 @@
Feature: Edit products within the cart
As a shopper I want to be able to add multiple products to my cart,
and edit my cart before entering checkout.
@editCart
Scenario: Shopper is able to edit products in their cart
When shopper selects yes or no for tracking consent
Given Shopper searches for "Elbow Sleeve Ribbed Sweater"
Then selects size "S"
Then shopper changes product quantity
Then he adds the product to cart
Given Shopper searches for "Modern Striped Dress Shirt"
Then selects size "16R"
Then he adds the product to cart
Then shopper edits products in cart

View File

@@ -0,0 +1,11 @@
Feature: Add Product To Cart
As a shopper, I want to search for a product and add it to cart
@homePage @cart
Scenario: Shopper is able to add a product to a cart
When shopper selects yes or no for tracking consent
Given Shopper searches for "Elbow Sleeve Ribbed Sweater"
Then selects size "S"
Then shopper changes product quantity
Then he adds the product to cart
Then he is able to see the correct product in cart

View File

@@ -0,0 +1,8 @@
Feature: Email signup
As a shopper, I want to signup to mailing list
@homePage
Scenario: Shopper is able to enter email for signup
When shopper selects yes or no for tracking consent
Then shopper enters email in signup form
And shopper subscribes to the email list

View File

@@ -0,0 +1,6 @@
Feature: Land Home Page
As a shopper, I want to land on the home Page
@homePage
Scenario: Shopper is able to land on the home Page
When shopper selects yes or no for tracking consent

View File

@@ -0,0 +1,9 @@
Feature: Store locator
As a shopper, I want to view available store locations
@homePage
Scenario: Shopper is able to use store locator.
When shopper selects yes or no for tracking consent
Then shopper goes to store locator page
And shopper searches for a store
Then shopper searches for a store with different radius

View File

@@ -0,0 +1,15 @@
Feature: Modify & Verify Mini Cart
As a shopper, I want to verify selected product attributes and modify (edit quantity and remove product) mini cart
@miniCart @miniCartGuestUser
Scenario: Shopper is able to modify mini cart, verify selected product attributes and goto Guest Checkout
Given shopper selects yes or no for tracking consent
When shopper is able to add and remove a product from minicart
And shopper is able to add a product and edit product quantity in minicart
Then shopper goes to Guest Checkout page from minicart
@miniCart @miniCartRegisteredUser
Scenario: Shopper is able to modify mini cart, verify selected product attributes and goto Registered Checkout
Given shopper logs into the website
When shopper is able to add a product and edit product quantity in minicart
And shopper is able to navigate through minicart, registered checkout pages and remove the product from cart

View File

@@ -0,0 +1,18 @@
Feature: Create an Account
As a shopper, I want to be able to create an account with the site
@loginPage @createAccount @deepTest
Scenario: Shopper is able to create a new account from the login page
Given shopper goes to the Login Page
Then shopper is able to click tab to create account
And shopper is able fill out registration information with new email
And shopper is able to click the create account button
And shopper does not see a username is invalid error
@loginPage @createAccount
Scenario: Shopper is not able to create an account that already exists
Given shopper goes to the Login Page
Then shopper is able to click tab to create account
And shopper is able fill out registration information with existing email
And shopper is able to click the create account button
And shopper sees a username is invalid error

View File

@@ -0,0 +1,12 @@
Feature: Forgot Password
As a shopper, I want to be able to reset my password if I forgot my
login information
@loginPage @forgotPassword
Scenario: Shopper is able to reset their password
Given shopper goes to the Login Page
When shopper clicks forgot password
And shopper fills out their recovery email address
Then shopper should see request to change password prompt
# This is just half of the feature being tested with a dummy email
# Requires manual testing with a real email

View File

@@ -0,0 +1,14 @@
Feature: User Login
As a shopper, I want to be able to log into the site
@loginPage
Scenario: Shopper is able to log into the site from the home page
Given shopper logs into the website
@loginPage @mobile
Scenario: Shopper is able to log into the site mobile
Given shopper logs into the website on phone
@loginPage @tablet
Scenario: Shopper is able to log into the site tablet
Given shopper logs into the website on tablet

View File

@@ -0,0 +1,12 @@
Feature: Campaign Banner on Page Designer Home Page
As a shopper, I shoiuld see the campaign banner
@campaignBanner @pageDesigner
Scenario: Shopper should able to see the campaign banner
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the campaign banner
And shopper should see the campaign banner message
And shopper should see a close button on campaign banner
And shopper should be able to close the campaign banner
And shopper should no longer see the campaign banner

View File

@@ -0,0 +1,24 @@
Feature: Page Designer Carousel
As a shopper, I want to see the page designer carousel
@Carousel @pageDesigner
Scenario: Shopper is able to interact with the page designer carousel component
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
And Shopper sees the carousel "1"
Given Shopper sees carousel controls in carousel "1"
When Shopper clicks next in carousel "1" 1 time
Then Shopper should see the next slide in the first carousel
When Shopper clicks previous in carousel "1"
Then Shopper should see the previous slide in the first carousel
@Carousel @pageDesigner
Scenario: Shopper is able to interact with the page designer carousel-2 component
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
And Shopper sees the carousel "2"
Given Shopper sees carousel controls in carousel "2"
When Shopper clicks next in carousel "2" 5 times
Then Shopper should see next product in the second carousel
When Shopper clicks previous in carousel "2"
Then Shopper should see previous slide in the second carousel

View File

@@ -0,0 +1,9 @@
Feature: category on Page Designer Home Page
As a shopper, I want to see the category component
@category @pageDesigner
Scenario: Shopper is able to see the category
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the category components
And shopper can click on a category link

View File

@@ -0,0 +1,10 @@
Feature: Image And Text Component on Page Designer Home Page
As a shopper, I should see the Image And Text Component
@ITC @pageDesigner
Scenario: Shopper should be able to see the Image And Text Component
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the image and text component
Then shopper should see the overlay message
Then shopper should go to new arrivals page clicking on the image

View File

@@ -0,0 +1,10 @@
Feature: Main Banner on Page Designer Home Page
As a shopper, I should see the main banner
@mainBanner @pageDesigner
Scenario: Shopper should able to see the main banner
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the main banner
Then shopper should see the main banner message
Then shopper should go to womens clothing dresses clicking on the main banner

View File

@@ -0,0 +1,8 @@
Feature: Photo Tile Component on Page Designer Home Page
As a shopper, I should see the Photo Tile Component
@photoTile @pageDesigner
Scenario: Shopper should be able to see the Photo Tile Component
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the photo tile component

View File

@@ -0,0 +1,10 @@
Feature: Popular Category on Page Designer Home Page
As a shopper, I want to see the popular category component
@popularCategory @pageDesigner
Scenario: Shopper is able to see the popular category
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the popularCategories layout
Then shopper should see the popularCategory components
And shopper can click on a popular category

View File

@@ -0,0 +1,18 @@
Feature: Product Tile on Page Designer Home Page
As a shopper, I should see the product Tile
@productTile @pageDesigner
Scenario: Shopper should able to see the product tile with default attributes
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the product tile component
Then shopper should see the alt attribute on product image
Then shopper should see the title attribute on product image
Then shopper should not see quickview on product tile
Then shopper should see the product name on product tile
Then shopper should see the regular price on product tile
Then shopper should see the strike-through price on product tile
Then shopper should see the sales price on product tile
Then shopper should go to the product details page clicking on the image
Then shopper load Page Designer home page
Then shopper should go to the product details page clicking on product name

View File

@@ -0,0 +1,9 @@
Feature: Rich Text Component on Page Designer Home Page
As a shopper, I should see the Rich Text Component
@richText @pageDesigner
Scenario: Shopper should be able to see the rich text Component
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the rich text component
Then shopper should see the title

View File

@@ -0,0 +1,11 @@
Feature: Shop Category on Page Designer Home Page
As a shopper, I should see the Shop Category
@shopCategory @pageDesigner
Scenario: Shopper should able to see the Shop Category on Page Designer Home Page
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the shop category heading
Then shopper should see 5 shop categories
Then shopper should go to the category page by clicking on the category link

View File

@@ -0,0 +1,10 @@
Feature: Shop The Look Component on Page Designer Home Page
As a shopper, I should see the Shop The Look Component
@shopTheLook @pageDesigner
Scenario: Shopper should be able to see the shop the look Component
When shopper load Page Designer home page
Then shopper accept the Consent Tracking Modal
Then shopper should see the shop the look component
Then shopper should see the title when hover over image
Then shopper should not see the setItem when hover over image on product

View File

@@ -0,0 +1,11 @@
Feature: Filter products from PDP
As a shopper I want navigate back to the previous plp using the back button.
@productBackButton
Scenario: Shopper is able to go back to refined plp from pdp
When shopper selects yes or no for tracking consent
Given shopper searches for category from menu
And shopper clicks on the more button
Then Shopper clicks on the first product Tile
And Shopper clicks the back button on pdp

View File

@@ -0,0 +1,13 @@
Feature: Filter products from PDP
As a shopper I want to be able to search for a product type
And then select different filter options to reduce the number of potential
items.
@productFilter
Scenario: Shopper is able to filter for products
When shopper selects yes or no for tracking consent
Given shopper searches for category from menu
And shopper filters product by color
And shopper filters product by size
And shopper filters product by price
And shopper filters product by option

View File

@@ -0,0 +1,9 @@
Feature: Product Quickview
As a shopper I want to be able to search for a product from the menu
then add the product to cart using Quick View
@productQuickView
Scenario: Shopper is able to shop using a product's quick view
When shopper selects yes or no for tracking consent
And shopper opens product quick view from home page
Then shopper adds to cart from Quick View

View File

@@ -0,0 +1,25 @@
Feature: Product Detail Page Simple Layout
As a shopper, I want to see Product Details for a Simple Product
Background: shoper is on product details page
When shopper goes to the Product Detail Page
@simpleProductDetail
Scenario: Shopper sees all the product related information on the Simple product page
Then shopper sees all the product related information
@simpleProductDetail_breadcrumbs
Scenario: Shopper sees the correct breadcrumbs and is on right navigation path
Then shopper sees the correct breadcrumbs
@simpleProductDetail_socialLinks
Scenario: Shopper sees the correct social links
Then shopper sees the correct social links
@simpleProductDetail_addToCartButton
Scenario: Shopper sees the Add to Cart Button Enabled
Then shopper is able to see Add to Cart Button Enabled
@simpleProductDetail_addToCartButton
Scenario: Shopper is able to copy Product URL using Copy Link Icon
Then shopper is able to copy Product URL using Copy Link Icon

View File

@@ -0,0 +1,8 @@
Feature: Use a source code to land on a category page
As a shopper I want to be able land on a category landing page using a sourcecode link
@sourceCodeRedirect
Scenario: Use a source code to land on a category page
Then shopper lands on the expected category landing page
And shopper sees all the category landing page related information

View File

@@ -0,0 +1,8 @@
Feature: Use a source code to land on a content page
As a shopper I want to be able land on a content page using a sourcecode link
@sourceCodeRedirect
Scenario: Shopper uses the src code to go to a content page
Then shopper lands on the expected content page
And shopper sees the expected content page

View File

@@ -0,0 +1,8 @@
Feature: Use a source code to land on a pdp page
As a shopper I want to be able land on a pdp page using a sourcecode link
@sourceCodeRedirect
Scenario: Shopper uses the src code to go to a pdp
Then shopper lands on the expected pdp
And shopper sees all the product related information v2

View File

@@ -0,0 +1,19 @@
Feature: Follow the happy path of a guest user
As a shopper, I want to shop for a product and fill out the correct
shipping information/billing information in checkout.
@happyPath
Scenario: Guest shopper should be able to follow the checkout flow
When shopper selects yes or no for tracking consent
Given Shopper searches for "Elbow Sleeve Ribbed Sweater"
Then selects size "S"
Then he adds the product to cart
Then shopper goes to cart
Then shopper changes product quantity to "2"
And shopper selects checkout from cart
And shopper selects checkout as guest
And shopper fills out shipping information
Then shopper proceeds to payment section
And shopper fills out billing information
Then shopper places order
And shopper verifies the order confirmation page

View File

@@ -0,0 +1,28 @@
Feature: Follow the happy path of a registered user
As a shopper, I want to shop for a product, log into my account, and fill out the correct
shipping information based on previous saved user data.
Background:
Given shopper logs into the website
And shopper clicks add new payment
And shopper fills out their payment information
@happyPath @testing
Scenario: Registered shopper should be able to follow the checkout flow
Given Shopper searches for "Elbow Sleeve Ribbed Sweater"
Then selects size "S"
Then he adds the product to cart
Then shopper goes to cart
Then shopper changes product quantity to "2"
And shopper selects checkout from cart
And shopper verifies shipping information
Then shopper proceeds to payment section
And shopper fills out registered user billing information
Then shopper places order
And shopper verifies the order confirmation page
Then shopper goes to profile saved payments page and deletes credit card
And logs out of the account
Given shopper goes to the Login Page
Then shopper is able to fill out the order number, email, and zip code
And shopper is able to click the check status button
And shopper is able to view order detail

View File

@@ -0,0 +1,221 @@
{
"include": {
"data": "./test/acceptance/metadata.json",
"homePage": "./test/acceptance/pages/home.page.js",
"productPage": "./test/acceptance/pages/product.page.js",
"cartPage": "./test/acceptance/pages/cart.page.js",
"checkoutPage": "./test/acceptance/pages/checkout.page.js",
"loginPage": "./test/acceptance/pages/login.page.js",
"accountPage": "./test/acceptance/pages/account.page.js",
"pageDesigner": "./test/acceptance/pages/pageDesigner.page.js",
"utilities": "./test/acceptance/utilities.js"
},
"gherkin_steps": [
"./test/acceptance/steps/homePage/addProductToCart.steps.js",
"./test/acceptance/steps/homePage/emailSignup.steps.js",
"./test/acceptance/steps/homePage/landHomePage.steps.js",
"./test/acceptance/steps/homePage/locateStore.steps.js",
"./test/acceptance/steps/productDetailPage/pdpSimpleLayout.steps.js",
"./test/acceptance/steps/productDetailPage/pdpQuickViewSearch.steps.js",
"./test/acceptance/steps/productDetailPage/pdpProductFilter.steps.js",
"./test/acceptance/steps/productDetailPage/pdpBackToPlp.steps.js",
"./test/acceptance/steps/checkoutPage/editCart.steps.js",
"./test/acceptance/steps/loginPage/createAccount.steps.js",
"./test/acceptance/steps/loginPage/loginUser.steps.js",
"./test/acceptance/steps/loginPage/forgotPassword.steps.js",
"./test/acceptance/steps/accountPage/editProfile.steps.js",
"./test/acceptance/steps/accountPage/changePassword.steps.js",
"./test/acceptance/steps/accountPage/addPayment.steps.js",
"./test/acceptance/steps/accountPage/addAddress.steps.js",
"./test/acceptance/steps/testSuites/happyPath.steps.js",
"./test/acceptance/steps/utilities.steps.js",
"./test/acceptance/steps/pageDesigner/campaignBanner/campaignBanner.steps.js",
"./test/acceptance/steps/pageDesigner/mainBanner/mainBanner.steps.js",
"./test/acceptance/steps/pageDesigner/popularCategory/popularCategory.steps.js",
"./test/acceptance/steps/pageDesigner/category/category.steps.js",
"./test/acceptance/steps/pageDesigner/imageAndText/imageAndText.steps.js",
"./test/acceptance/steps/pageDesigner/photoTile/photoTile.steps.js",
"./test/acceptance/steps/pageDesigner/productTile/productTile.steps.js",
"./test/acceptance/steps/pageDesigner/shopCategory/shopCategory.steps",
"./test/acceptance/steps/pageDesigner/richText/richText.steps.js",
"./test/acceptance/steps/pageDesigner/shopTheLook/shopTheLook.steps.js",
"./test/acceptance/steps/pageDesigner/carousel/carousel.steps.js",
"./test/acceptance/steps/sourceCodeRedirects/pdpRedirect.steps.js",
"./test/acceptance/steps/sourceCodeRedirects/categoryRedirect.steps.js",
"./test/acceptance/steps/sourceCodeRedirects/pageRedirect.steps.js"
],
"user1": {
"fName": "Test1",
"lName": "User1",
"address1": "104 Presidential Way",
"country": "United States",
"state": "Massachusetts",
"stateAbr": "MA",
"city": "Woburn",
"zip": "01801",
"phone": "781-555-1212",
"email": "testuser1@demandware.com",
"password": "Test123!"
},
"CC": {
"ccNum": "4111111111111111",
"ccSecCode": "555",
"expMonth": "08",
"expYear": "2023",
"ccExpDate": "8/2023"
},
"product": {
"name": "Elbow Sleeve Ribbed Sweater",
"quantity": "2",
"editCartQuantity": "1",
"itemPrice": "$65.99",
"totalItemPrice": "$131.98",
"shipping": "$7.99",
"tax": "$7.00",
"estimatedTotal": "$146.97"
},
"product2": {
"name": "Modern Striped Dress Shirt",
"quantity": "1",
"color": "blue",
"size": "16R"
},
"product3": {
"name": "Woven Trimmed Cardigan.",
"quantity": "1",
"color": "White",
"size": "L",
"productLinkQV": "/on/demandware.store/Sites-RefArch-Site/en_US/Product-ShowQuickView?pid=701644391737M"
},
"product4": {
"searchWord": "Long Sleeve Embellished",
"name": "Long Sleeve Embellished Boat Neck Top",
"color": "Begonia Pink",
"colorAttribute": "Color: Begonia Pink",
"size": "S",
"sizeAttribute": "Size: S",
"availability": "In Stock",
"originalQuantity": "2",
"editQuantity": "1",
"finalQuantity": "2",
"originalPrice": "$57.98",
"finalPrice": "$28.99",
"afterRemoveQuantity": "0",
"pid": "701642823896M"
},
"searchPages": {
"womensTops": "/on/demandware.store/Sites-RefArch-Site/en_US/Search-Show?cgid=womens-clothing-tops"
},
"orderHistory": {
"number": "00004201",
"email": "testuser1@demandware.com",
"zip": "01801"
},
"filterProduct": {
"color": "white",
"colorTotalItems": "79 Results",
"size": "12",
"sizeTotalItems": "11 Results",
"price": "$20 - $49.99",
"priceTotalItems": "2 Results",
"option": "Price Low To High",
"productName": "Long Sleeve Seamed Button Front Shirt"
},
"storeLocator": {
"pageURL": "/on/demandware.store/Sites-RefArch-Site/en_US/Stores-Find?showMap=true&horizontalView=true&isForm=true",
"zipCode": "01801",
"numStores": "5",
"radius": "300",
"numStoresRadius": "11"
},
"home": {
"email": "testuser1@demandware.com"
},
"login": {
"loginPage": "/on/demandware.store/Sites-RefArch-Site/en_US/Account-Show?registration=false",
"homePage": "/on/demandware.store/Sites-RefArch-Site/en_US/Home-Show",
"email": "testuser1@demandware.com",
"password": "Test123!",
"fName": "John",
"lName": "Smith",
"phone": "781-555-1212",
"newRegEmail": "jsmith@email.com",
"loginHomeScreen": "span.user-message",
"emailLogin": "#login-form-email",
"passwordLogin": "#login-form-password",
"primaryButton": ".btn.btn-block.btn-primary",
"registrationError": "Username is invalid."
},
"checkout": {
"fName": "Test1",
"lName": "User1",
"address1": "104 Presidential Way",
"country": "United States",
"state": "Massachusetts",
"stateAbr": "MA",
"city": "Woburn",
"zip": "01801",
"phone": "781-555-1212",
"email": "testuser1@demandware.com",
"ccNum": "4111111111111111",
"ccSecCode": "555",
"expMonth": "08",
"expYear": "2023",
"ccExpDate": "8/2023"
},
"account": {
"accountPage": "/on/demandware.store/Sites-RefArch-Site/en_US/Account-Show",
"name": "John Smith",
"addressTitle": "Apartment",
"addressHome": "Home",
"newPassword": "Test123!",
"deletePaymentModalText": "Delete Payment?"
},
"pageDesigner": {
"richTextTitle" : "What's New Trending",
"shopTheLookOverlayText": "Spring Look",
"shopTheLookSetItems": "3 Items",
"shopTheLookButton": "Shop The Look",
"shopTheLookProductName": "Short Sleeve Raglan Smock Shirt.",
"imageAndTextOverlayText": "Summer Look",
"imageAndTextNewArrival": "/s/RefArch/new arrivals/?lang=default",
"campaignBannerMessage": "We're Taking Sale To the Next Level! 80% OFF!",
"category1": "Shoes",
"category2": "Scarves",
"category3": "Accessories",
"category4": "Men's New Arrivals",
"category5": "Women's New Arrivals",
"categoryLink": "/s/RefArch/womens/?lang=default",
"mainBannerHeading": "Dresses\nfor\nBesties",
"mainBannerHeading2":"Summer Sales",
"mainBannerSubHeading": "Shop Now",
"mainBannerLink": "/s/RefArch/womens/clothing/dresses/?lang=default",
"popularCategory1": "Outfits",
"popularCategory2": "Tops",
"popularCategory3": "Dresses",
"popularCategory4": "Bottoms",
"popularCategory5": "Jackets & Coats",
"popularCategory6": "Feeling Red",
"productTileQuickView": "Quick Shop",
"productTileProductName": "Floral Print Pencil Skirt.",
"productTileProductName5": "Incase",
"productTile1ProductPrice": "$129.00",
"productTile3ProductStrikeThroughPrice": "$59.00",
"productTile3ProductPrice": "$43.99",
"productTile1PDPLink": "/s/RefArch/floral-print-pencil-skirt/25696881M.html?lang=default",
"shopCategory1": "Women's New Arrivals",
"shopCategory2": "Men's New Arrivals",
"shopCategory3": "Shoes",
"shopCategory4": "Scarves",
"shopCategory5": "Accessories",
"shopCategoryTitle": "Shop Category",
"shopCategoryLink": "/s/RefArch/womens/accessories/shoes/?lang=default"
}
}

View File

@@ -0,0 +1,123 @@
const I = actor();
module.exports = {
locators: {
addressTitle: '#addressId.form-control',
fName: '#firstName.form-control',
lName: '#lastName.form-control',
address1: '#address1.form-control',
country: '#country.form-control',
state: '#state.form-control',
city: '#city.form-control',
zip: '#zipCode.form-control',
phone: '#phone.form-control',
saveBtn: '.btn.btn-save.btn-block.btn-primary',
nameOnCard: '#cardOwner.form-control',
ccNum: '#cardNumber.form-control',
expMonth: '#month.form-control',
expYear: '#year.form-control',
defaultPayment: '.custom-control-label',
currentPassword: '#currentPassword.form-control',
newPassword: '#newPassword.form-control',
newPasswordConfirm: '#newPasswordConfirm.form-control',
confirmEmail: '#confirmEmail.form-control',
confirmPassword: '#password.form-control',
addNew: '.card-link',
backToAccount: '.text-center.back-to-account-link',
viewAll: '.pull-right',
removeProductBtn: '.remove-btn.remove-payment.btn-light',
removeProductModal: '.modal-content',
removeProductConfirm: '.btn.btn-primary.delete-confirmation-btn',
loggedInAccountNav: '.user.nav-item',
accountLogOut: '.user .popover li'
},
addAddress(addressTitle, fName, lName, address1, country, state, city, zipcode, phone) {
I.fillField(this.locators.addressTitle, addressTitle);
I.fillField(this.locators.fName, fName);
I.fillField(this.locators.lName, lName);
I.fillField(this.locators.address1, address1);
I.selectOption(this.locators.country, country);
I.selectOption(this.locators.state, state);
I.fillField(this.locators.city, city);
I.fillField(this.locators.zip, zipcode);
I.fillField(this.locators.phone, phone);
I.click(this.locators.saveBtn);
},
clickAddAddress() {
let locator = locate(this.locators.addNew)
.withAttr({ 'aria-label': 'Add New Address' });
I.click(locator);
},
clickAddPayment() {
let locator = locate(this.locators.addNew)
.withAttr({ 'aria-label': 'Add New Payment' });
I.click(locator);
},
clickEditProfile() {
let locator = locate(this.locators.viewAll)
.withAttr({ 'aria-label': 'Edit Profile' });
I.click(locator);
},
clickEditPassword() {
let locator = locate(this.locators.viewAll)
.withAttr({ 'aria-label': 'Change Password' });
I.click(locator);
},
clickAddressBook() {
let locator = locate(this.locators.viewAll)
.withAttr({ 'aria-label': 'View Address Book' });
I.click(locator);
},
clickEditAddress(addName) {
let locator = locate(this.locators.viewAll)
.withAttr({ 'aria-label': `Edit Address : ${addName} (Default Address)` });
I.click(locator);
},
editAddress(addName) {
let locator = locate('#addressId.form-control');
I.wait(1);
I.fillField(locator, addName);
I.wait(1);
I.click(this.locators.saveBtn);
},
addPayment(nameOnCard, ccNum, expMonth, expYear) {
I.fillField(this.locators.nameOnCard, nameOnCard);
I.fillField(this.locators.ccNum, ccNum);
I.scrollTo(this.locators.expMonth);
I.selectOption(this.locators.expMonth, expMonth);
I.selectOption(this.locators.expYear, expYear);
I.click(this.locators.defaultPayment);
I.click(this.locators.saveBtn);
I.click(this.locators.backToAccount);
},
viewAllPayments() {
let locator = locate(this.locators.viewAll)
.withAttr({ 'aria-label': 'View saved payment methods' });
I.click(locator);
},
removePayment(deletePaymentModalText) {
let locator = locate(this.locators.removeProductBtn).last();
I.click(locator);
I.waitForText(deletePaymentModalText);
within(this.locators.removeProductModal, () => {
I.click(this.locators.removeProductConfirm);
});
},
changePassword(currentPassword, newPassword) {
I.fillField(this.locators.currentPassword, currentPassword);
I.fillField(this.locators.newPassword, newPassword);
I.fillField(this.locators.newPasswordConfirm, newPassword);
I.click(this.locators.saveBtn);
},
editProfile(phone, email, password) {
I.fillField(this.locators.phone, phone);
I.fillField(this.locators.confirmEmail, email);
I.fillField(this.locators.confirmPassword, password);
I.click(this.locators.saveBtn);
},
logOut() {
I.click(this.locators.loggedInAccountNav);
let locator = locate(this.locators.accountLogOut).last();
I.click(locator);
}
};

View File

@@ -0,0 +1,86 @@
const I = actor();
module.exports = {
locators: {
lineItemQuantity: '.form-control.quantity.custom-select',
totalItemQuantity: 'h2.number-of-items',
lineItemPriceTotal: 'span.value',
totalItemPrice: '.line-item-total-price',
shippingCost: '.text-right.shipping-cost',
taxTotal: '.text-right.tax-total',
estimatedTotal: '.text-right.grand-total',
cartIcon: '.minicart-icon.fa.fa-shopping-bag',
checkoutBtn: '.btn.btn-primary.btn-block.checkout-btn',
removeProductBox: '.hidden-md-down',
removeProductBtn: '.remove-btn-lg.remove-product.btn.btn-light',
removeProductModal: '.modal-content',
removeProductModalConfirm: '.btn.btn-primary.cart-delete-confirmation-btn',
editQuantitySelector: '.form-control.quantity.custom-select',
miniCartEditQty: 'select[data-pid="<pid>"]',
lineItemName: '.line-item-name',
miniCartLineItemName: '.line-item-name > span',
lineItemAttributes: '.item-attributes .line-item-attributes',
subTotal: '.text-right.sub-total',
removeProductButton: '.remove-btn.remove-product',
removeFromMiniCartButton: 'button[data-pid="<pid>"]',
miniCartQuantity: '.minicart-quantity',
miniCartPopover: '.popover.popover-bottom.show'
},
verifyCart(totalQuantity, itemPrice, totalItemPrice, shipping, tax, estimatedTotal) {
I.see(totalQuantity, this.locators.lineItemQuantity);
I.see(itemPrice, this.locators.lineItemPriceTotal);
I.see(totalItemPrice, this.locators.totalItemPrice);
I.see(shipping, this.locators.shippingCost);
I.see(tax, this.locators.taxTotal);
I.see(estimatedTotal, this.locators.estimatedTotal);
},
verifyCartQuantity(totalQuantity) {
I.see(totalQuantity + ' Items', this.locators.totalItemQuantity);
},
verifyMiniCartOriginal(product) {
I.scrollPageToTop();
I.executeScript(function (el) { $(el).trigger('touchstart'); }, this.locators.cartIcon);
this.verifyMiniCart(product);
I.see(product.originalQuantity, this.locators.lineItemQuantity);
I.see(product.originalPrice, this.locators.subTotal);
},
verifyMiniCartUpdated(product) {
this.verifyMiniCart(product);
I.see(product.finalQuantity, this.locators.lineItemQuantity);
I.see(product.finalPrice, this.locators.subTotal);
},
verifyMiniCart(product) {
I.see(product.name, this.locators.miniCartLineItemName);
I.see(product.colorAttribute, this.locators.lineItemAttributes);
I.see(product.sizeAttribute, this.locators.lineItemAttributes);
I.see(product.availability, this.locators.lineItemAttributes);
},
removeProductFromMiniCart(product) {
I.scrollPageToTop();
I.executeScript(function (el) { $(el).trigger('touchstart'); }, this.locators.cartIcon);
I.click(this.locators.removeFromMiniCartButton.replace('<pid>', product.pid));
// Confirm remove product
within(this.locators.removeProductModal, () => {
I.click(this.locators.removeProductModalConfirm);
});
},
removeProduct(productName) {
// Click x to remove product
let locator = locate(this.locators.removeProductBox)
.find(this.locators.removeProductBtn)
.withAttr({ 'data-name': productName });
I.click(locator);
// Confirm remove product
within(this.locators.removeProductModal, () => {
I.click(this.locators.removeProductModalConfirm);
});
},
editQuantity(quantity) {
I.selectOption(this.locators.editQuantitySelector, quantity);
},
editMiniCartQuantity(product) {
within(this.locators.miniCartPopover, () => {
I.selectOption(this.locators.miniCartEditQty.replace('<pid>', product.pid), product.editQuantity);
});
}
};

View File

@@ -0,0 +1,196 @@
const I = actor();
module.exports = {
locators: {
lineItemName: 'div.line-item-name',
checkoutAsGuestBtn: '.btn.btn-primary.btn-block.submit-customer',
checkoutAsRegisteredBtn: '.btn.btn-block.btn-primary',
emailGuest: '#email-guest',
emailRegistered: '#email',
password: '#login-form-password',
fName: '.form-control.shippingFirstName',
lName: '.form-control.shippingLastName',
address1: '.form-control.shippingAddressOne',
country: '.form-control.shippingCountry',
state: '.form-control.shippingState',
city: '.form-control.shippingAddressCity',
zip: '.form-control.shippingZipCode',
phone: '.form-control.shippingPhoneNumber',
toPayment: '.btn.btn-primary.btn-block.submit-shipping',
payPhone: '#phoneNumber',
payCard: '#cardNumber',
payExpMonth: '#expirationMonth',
payExpYear: '#expirationYear',
paySecCode: '#securityCode',
paySecCodeSaved: '.form-control.saved-payment-security-code',
placeOrder: '.btn.btn-primary.btn-block.submit-payment',
confirmOrder: '.btn.btn-primary.btn-block.place-order',
billingConfirmation: '.addressSelector.form-control',
shipping_addSelector: '.addressSelector',
shipping_methodBlock: '.shipping-method-block',
shipping_methodOptions: '.form-check.col-9.start-lines',
checkout_shippingSection: '.card.shipping-summary',
checkout_prefilledShippingInfo: '.addressSelector.form-control',
checkout_paymentSection: '.card.payment-summary',
checkout_orderSummary: '.card-body.order-total-summary',
orderConf_thankYou: '.order-thank-you-msg',
orderConf_shippingSection: '.summary-details.shipping',
orderConf_billingSection: '.summary-details.billing',
orderConf_paymentSection: '.payment-details',
orderConf_quantity: '.line-item-pricing-info',
orderConf_totalSection: '.order-total-summary',
orderConf_orderNumber: 'summary-details.order-number',
homeLink: 'a>img.hidden-md-down',
checkoutStage: '.data-checkout-stage'
},
fillPersonalDataGuest(email) {
I.fillField(this.locators.emailGuest, email);
},
fillShippingInfo(fName, lName, address1, country, state, city, zipcode, phone) {
I.scrollTo(this.locators.fName);
I.fillField(this.locators.fName, fName);
I.fillField(this.locators.lName, lName);
I.fillField(this.locators.address1, address1);
I.waitForElement(this.locators.country);
I.selectOption(this.locators.country, country);
I.waitForElement(this.locators.state);
I.selectOption(this.locators.state, state);
I.wait(3);
I.fillField(this.locators.city, city);
I.fillField(this.locators.phone, phone);
I.fillField(this.locators.zip, zipcode);
},
fillPaymentInfoGuest(fName, lName, address1, city, stateAbr, zipcode, phone, ccNum, expMonth, expYear, ccSecCode) {
I.waitForElement(this.locators.checkout_prefilledShippingInfo);
I.see(fName, this.locators.checkout_prefilledShippingInfo);
I.see(lName, this.locators.checkout_prefilledShippingInfo);
I.see(address1, this.locators.checkout_prefilledShippingInfo);
I.see(city, this.locators.checkout_prefilledShippingInfo);
I.see(stateAbr, this.locators.checkout_prefilledShippingInfo);
I.see(zipcode, this.locators.checkout_prefilledShippingInfo);
I.fillField(this.locators.payPhone, phone);
I.fillField(this.locators.payCard, ccNum);
I.waitForElement(this.locators.payExpMonth, expMonth);
I.selectOption(this.locators.payExpMonth, expMonth);
I.waitForElement(this.locators.payExpYear, expYear);
I.selectOption(this.locators.payExpYear, expYear);
I.waitForElement(this.locators.paySecCode);
I.fillField(this.locators.paySecCode, ccSecCode);
},
fillPaymentInfoRegistered(phone, ccSecCode) {
I.fillField(this.locators.payPhone, phone);
I.waitForElement(this.locators.paySecCodeSaved);
I.fillField(this.locators.paySecCodeSaved, ccSecCode);
},
verifyCart(quantity, itemPrice, totalItemPrice, shipping, tax, estimatedTotal) {
I.waitForElement(this.locators.lineItemQuantity);
I.waitForText(quantity, this.locators.lineItemQuantity);
I.waitForElement(this.locators.totalItemQuantity);
I.waitForText(quantity + ' Items', this.locators.totalItemQuantity);
I.waitForElement(this.locators.lineItemPriceTotal);
I.waitForText(itemPrice, this.locators.lineItemPriceTotal);
I.waitForElement(this.locators.totalItemPrice);
I.waitForText(totalItemPrice, this.locators.totalItemPrice);
I.waitForElement(this.locators.shippingCost);
I.waitForText(shipping, this.locators.shippingCost);
I.waitForElement(this.locators.taxTotal);
I.waitForText(tax, this.locators.taxTotal);
I.waitForElement(this.locators.estimatedTotal);
I.waitForText(estimatedTotal, this.locators.estimatedTotal);
},
fillReturnCustomerInfo(email, password) {
I.waitForElement(this.locators.email);
I.fillField(this.locators.email, email);
I.waitForElement(this.locators.password);
I.fillField(this.locators.password, password);
},
verifyShipping(fname, lname, add1, city, stateAbr, zip) {
I.waitForElement(this.locators.shipping_addSelector);
I.waitForText(`${fname} ${lname} ${add1}`, this.locators.shipping_addSelector);
I.waitForText(`${city}, ${stateAbr} ${zip}`, this.locators.shipping_addSelector);
I.waitForElement(this.locators.shipping_methodBlock);
I.seeNumberOfVisibleElements(this.locators.shipping_methodOptions, 3);
},
verifyBilling() {
// Check for best way to verify this one
I.waitForElement(this.locators.billingConfirmation);
I.waitForText(fName + lName + address1);
},
verifyCheckoutInfo(fName, lName, add1, city, zip, phone, ccNum, ccExpDate, quantity,
totalItemPrice, shipping, tax, estimatedTotal) {
// verify shipping address is correct
I.scrollTo(this.locators.checkout_shippingSection);
I.see(fName, this.locators.checkout_shippingSection);
I.see(lName, this.locators.checkout_shippingSection);
I.see(add1, this.locators.checkout_shippingSection);
I.see(city, this.locators.checkout_shippingSection);
I.see(zip, this.locators.checkout_shippingSection);
I.see(phone, this.locators.checkout_shippingSection);
// verify billing address is correct
I.scrollTo(this.locators.checkout_paymentSection);
I.see(fName, this.locators.checkout_paymentSection);
I.see(lName, this.locators.checkout_paymentSection);
I.see(add1, this.locators.checkout_paymentSection);
I.see(city, this.locators.checkout_paymentSection);
I.see(zip, this.locators.checkout_paymentSection);
I.see(phone, this.locators.checkout_paymentSection);
// verify payment info is correct
// Leave the last 4 digits shown; replace everything else with '*'
I.see(ccNum.replace(/\d(?=\d{4})/g, '*'), this.locators.checkout_paymentSection);
I.see(ccExpDate, this.locators.checkout_paymentSection);
// verify product info is correct
I.scrollTo(this.locators.orderConf_quantity);
I.see(quantity, this.locators.orderConf_quantity);
I.see(totalItemPrice, this.locators.checkout_orderSummary);
I.see(shipping, this.locators.checkout_orderSummary);
I.see(tax, this.locators.checkout_orderSummary);
I.see(estimatedTotal, this.locators.checkout_orderSummary);
},
verifyOrderConfirmation(fName, lName, add1, city, zip, phone, email, ccNum, ccExpDate, quantity,
totalItemPrice, shipping, tax, estimatedTotal) {
// verify order is place successfully by verifying the order confirmation page
I.scrollTo(this.locators.orderConf_thankYou);
I.see('Thank you for your order.', this.locators.orderConf_thankYou);
// verify shipping address is correct
I.scrollTo(this.locators.orderConf_shippingSection);
I.see(fName, this.locators.orderConf_shippingSection);
I.see(lName, this.locators.orderConf_shippingSection);
I.see(add1, this.locators.orderConf_shippingSection);
I.see(city, this.locators.orderConf_shippingSection);
I.see(zip, this.locators.orderConf_shippingSection);
I.see(phone, this.locators.orderConf_shippingSection);
// verify billing address is correct
I.scrollTo(this.locators.orderConf_billingSection);
I.see(fName, this.locators.orderConf_billingSection);
I.see(lName, this.locators.orderConf_billingSection);
I.see(add1, this.locators.orderConf_billingSection);
I.see(city, this.locators.orderConf_billingSection);
I.see(zip, this.locators.orderConf_billingSection);
I.see(email, this.locators.orderConf_billingSection);
I.see(phone, this.locators.orderConf_billingSection);
// verify payment info is correct
// Leave the last 4 digits shown; replace everything else with '*'
I.see(ccNum.replace(/\d(?=\d{4})/g, '*'), this.locators.orderConf_paymentSection);
I.see(ccExpDate, this.locators.orderConf_paymentSection);
// verify product info is correct
I.scrollTo(this.locators.orderConf_quantity);
I.see(quantity, this.locators.orderConf_quantity);
I.see(totalItemPrice, this.locators.orderConf_totalSection);
I.see(shipping, this.locators.orderConf_totalSection);
I.see(tax, this.locators.orderConf_totalSection);
I.see(estimatedTotal, this.locators.orderConf_totalSection);
},
gotoHomePageFromCheckout() {
I.click(this.locators.homeLink);
}
};

View File

@@ -0,0 +1,50 @@
const I = actor();
module.exports = {
locators: {
consentTrackModal: '.modal-content',
consentTrackAffirm: '.affirm.btn.btn-primary',
searchField: 'input.form-control.search-field',
searchedImage: 'a>img.swatch-circle',
loginButton: '.user-message',
subscribeEmail: 'input.form-control',
subscribeButton: '.subscribe-email',
emailSignup: '.email-signup-alert',
searchWomens: '#womens.nav-link.dropdown-toggle',
searchWomensClothing: '#womens-clothing.dropdown-link.dropdown-toggle',
searchWomensTops: '#womens-clothing-tops.dropdown-link',
searchStoreZipCode: '#store-postal-code',
searchStoreBtn: '.btn-storelocator-search',
searchStoreResults: '.results.striped',
searchStoreCard: '.card-body',
searchStoreRadius: '.form-control.custom-select.radius'
},
accept() {
within(this.locators.consentTrackModal, () => {
I.click(this.locators.consentTrackAffirm);
});
},
search(product) {
I.fillField(this.locators.searchField, product);
I.waitForElement(this.locators.searchedImage);
I.click(this.locators.searchedImage);
},
subscribeList(email) {
I.fillField('hpEmailSignUp', email);
},
searchMenu(productPage) {
I.amOnPage(productPage);
},
searchForStore(zip) {
I.fillField(this.locators.searchStoreZipCode, zip);
I.click(this.locators.searchStoreBtn);
},
verifyStoreResults(numStores) {
let locator = locate(this.locators.searchStoreCard)
.inside(this.locators.searchStoreResults);
I.seeNumberOfVisibleElements(locator, numStores);
},
changeStoreRadius(radius) {
I.selectOption(this.locators.searchStoreRadius, radius);
}
};

View File

@@ -0,0 +1,76 @@
const I = actor();
module.exports = {
locators: {
loginHomeScreen: 'span.user-message',
emailLogin: '#login-form-email',
passwordLogin: '#login-form-password',
primaryButton: '.btn.btn-block.btn-primary',
rememberMe: '.remember-me',
createAccount: '#register-tab',
firstName: '#registration-form-fname',
lastName: '#registration-form-lname',
phoneNum: '#registration-form-phone',
emailAdr: '#registration-form-email',
emailAdrConfirm: '#registration-form-email-confirm',
password: '#registration-form-password',
passwordConfirm: '#registration-form-password-confirm',
orderNumber: '#trackorder-form-number',
orderEmail: '#trackorder-form-email',
orderZipCode: '#trackorder-form-zip',
orderReceipt: '.card-body.order-total-summary',
forgotPassword: '#password-reset',
forgotPasswordForm: '#reset-password-email',
submitEmailBtn: '#submitEmailButton',
verifyPasswordModal: '.modal-content',
hamburgerLogin: '.navbar-toggler.d-md-none',
loginBtn: '.nav-item.d-lg-none',
loginBtnLink: 'a.nav-link'
},
login(email, password) {
// fill login form
I.waitForElement(this.locators.emailLogin);
I.waitForElement(this.locators.passwordLogin);
I.fillField(this.locators.emailLogin, email);
I.fillField(this.locators.passwordLogin, password);
// click login
I.waitForElement(this.locators.primaryButton);
I.click(this.locators.primaryButton);
},
createAccount(fName, lName, phone, email, password) {
I.fillField(this.locators.firstName, fName);
I.fillField(this.locators.lastName, lName);
I.fillField(this.locators.phoneNum, phone);
I.fillField(this.locators.emailAdr, email);
I.fillField(this.locators.emailAdrConfirm, email);
I.fillField(this.locators.password, password);
I.fillField(this.locators.passwordConfirm, password);
},
checkOrder(orderNum, orderEmail, billingZip) {
I.fillField(this.locators.orderNumber, orderNum);
I.fillField(this.locators.orderEmail, orderEmail);
I.fillField(this.locators.orderZipCode, billingZip);
},
verifyOrderHistory(product) {
I.see(product.totalItemPrice, this.locators.orderReceipt);
I.see(product.shipping, this.locators.orderReceipt);
I.see(product.tax, this.locators.orderReceipt);
I.see(product.estimatedTotal, this.locators.orderReceipt);
},
forgotPassword(email) {
I.wait(2); // Must wait because of modal fade chops the email param off randomly and fails the test
let locator = locate(this.locators.forgotPasswordForm)
.withAttr({ name: 'loginEmail' });
I.waitForElement(locator);
I.fillField(locator, email);
},
verifyPasswordReset() {
I.waitForElement(this.locators.submitEmailBtn);
I.click(this.locators.submitEmailBtn);
I.waitForElement(this.locators.verifyPasswordModal);
I.see('Request to Reset Your Password', this.locators.verifyPasswordModal);
I.waitForElement(this.locators.submitEmailBtn);
I.click(this.locators.submitEmailBtn);
}
};

View File

@@ -0,0 +1,88 @@
const I = actor();
var carousel2Item1Selector = '.carousel:nth-child(2) .carousel-item:nth-child(1)';
var prodTile1ComponentSel = carousel2Item1Selector + ' .product-tile-pd';
var carousel2Item3Selector = '.carousel:nth-child(2) .carousel-item:nth-child(3)';
var prodTile3ComponentSel = carousel2Item3Selector + ' .product-tile-pd';
var shopCategoryComponent = '.mobile-1r-1c .shop-category-component';
var shopTheLookCell1 = '.cell1 .shopthelook-figure-lg';
var shopTheLookCell4 = '.cell4 .shopthelook-figure-lg';
module.exports = {
locators: {
carouselNext: '.carousel-control-next',
carouselPrevious: '.carousel-control-prev',
mainBanner: '.mainbanner-container',
mainBannerHeading: '.image-heading-text',
mainBannerSubHeading: '.mainbanner-sub-text',
mainBannerLink: '.mainbanner-container a',
pageTitle: '.page-title',
ITC: '.ITC-container',
ITCOverlay: '.ITC-image-heading-text',
ITCImageLink: '.ITC-figure a',
photo: '.photo-tile-container',
richText: '.editorialRichText-component-container',
richTextTitle: '.text-center',
shopTheLookContainer: '.shop-the-look-container',
shopTheLookTextOverlay: shopTheLookCell1 + ' .product-text-center',
shopTheLookImage: '.shopthelook-figure-lg img',
shopTheLookSetItems: shopTheLookCell1 + ' .set-count-text-center',
shopTheLookButton: shopTheLookCell1 + ' .shopthelook-text',
shopTheLook4thImage: shopTheLookCell4 + ' img',
shopTheLookProductName: shopTheLookCell4 + ' .product-text-center',
shopTheLook4thSetItems: shopTheLookCell4 + ' .set-count-text-center',
shopTheLook4thButton: shopTheLookCell4 + ' .shopthelook-text',
campaignBanner: '.campaign-banner',
campaignBannerMessage: '.campaign-banner-message',
campaignBannerCloseButton: '.campaign-banner .close-button .close',
productTile1: prodTile1ComponentSel,
productTile1Image: carousel2Item1Selector + ' .product-tile-image .product-tile-component-image',
productTile1Quickview: prodTile1ComponentSel + ' .quick-shop',
productTile1ProductName: prodTile1ComponentSel + ' .product-name-link',
productTile1ProductPrice: prodTile1ComponentSel + ' .product-price .sales',
productTile3StrikeThroughPrice: prodTile3ComponentSel + ' .product-price .strike-through',
productTile3ProductPrice: prodTile3ComponentSel + ' .product-price .sales',
productTile1ImageLinkToPdp: carousel2Item1Selector + ' .product-tile-image a',
productTile1NameLinkToPdp: prodTile1ComponentSel + ' .product-name-link a',
productDetailPage: '.product-detail',
productDetailPageProductId: '.product-id',
shopCategoryHeading: shopCategoryComponent + ' .shop-category-header h3',
shopCategoryLabel: shopCategoryComponent + ' .shop-category-label',
shopCategoryLink1: shopCategoryComponent + ' .shop-category-label:nth-child(1) a',
shopCategoryLink2: shopCategoryComponent + ' .shop-category-label:nth-child(2) a',
shopCategoryLink3: shopCategoryComponent + ' .shop-category-label:nth-child(3) a',
shopCategoryLink4: shopCategoryComponent + ' .shop-category-label:nth-child(4) a',
shopCategoryLink5: shopCategoryComponent + ' .shop-category-label:nth-child(5) a'
},
clickPopulareCategory(index, selector, url) {
let locator = locate(selector)
.at(index);
I.seeElement(locator);
I.click(locator);
I.seeInCurrentUrl(url);
},
seeCarousel(position) {
I.seeElement('.carousel:nth-child(' + position + ')');
},
controlsVisible(position) {
I.seeElement('.carousel:nth-child(' + position + ') .carousel-control-next');
I.seeElement('.carousel:nth-child(' + position + ') .carousel-control-prev');
},
verifySlide(position, expectedText, limitingElement) {
I.seeTextEquals(expectedText, '.carousel:nth-child(' + position + ') .carousel-item.active ' + limitingElement);
},
carouselControlClick(position, control) {
I.click('.carousel:nth-child(' + position + ') ' + control);
I.wait(1);
}
};

View File

@@ -0,0 +1,153 @@
const I = actor();
module.exports = {
locators: {
button: 'button',
selectSize: '.select-size',
selectQuantity: '.quantity-select',
selectColor: '.color-attribute',
addToCartButton: '.add-to-cart',
addToCartButtonEnabled: '.add-to-cart:not(:disabled)',
miniCartIcon: '.minicart-icon.fa.fa-shopping-bag',
miniCartCheckoutButton: '.checkout-btn',
cartHeader: '.cart-header',
productImage: '.carousel-item.active > img',
navigationCrumbs: '.product-breadcrumb:not(.d-md-none) .breadcrumb-item a',
productName: '.product-name',
productId: '.product-id',
ratings: '.ratings',
productAvailability: '.availability-msg',
productPrice: '.prices .price .value',
socialShare: 'ul.social-icons a',
pinterest: '.fa-pinterest',
facebook: '.fa-facebook-official',
twitter: '.fa-twitter',
copyLink: '.fa-link',
productDescription: '.description-and-detail .description .content',
productDetails: '.description-and-detail .details .content',
copyLinkMsgVisible: '.copy-link-message:not(.d-none)',
addToCartSuccess: '.add-to-cart-messages .alert-success',
addToCartFailure: '.add-to-cart-messages .alert-danger',
filterColor: '.swatch-circle-',
filterSize: 'span.null',
filterPrice: 'span',
filterOption: '.custom-select',
filterPDP: '.pdp-link a.link',
productTotals: '.result-count.text-center',
qv_ProductBtn: '.quickview.hidden-sm-down',
qv_ColorBtn: '.color-attribute',
qv_SizeSelect: '.custom-select.form-control.select-size',
qv_AddToCart: '.add-to-cart-global.btn.btn-primary',
alertAddToCart: '.alert.alert-success.add-to-basket-alert',
moreButton: '.show-more .more',
firstProductTile: '.product-tile',
pdpClass: '.product-detail'
},
selectSize(size) {
I.waitForElement(this.locators.selectSize);
I.selectOption(this.locators.selectSize, size);
},
selectQuantity(quantity) {
I.waitForElement(this.locators.selectQuantity);
I.selectOption(this.locators.selectQuantity, quantity);
},
selectColor(color) {
let locator = locate(this.locators.selectColor)
.withAttr({ 'aria-label': 'Select Color ' + color });
I.waitForElement(locator);
I.click(locator);
},
addToCart() {
I.waitForEnabled(this.locators.addToCartButton);
I.click(this.locators.addToCartButton);
},
addProductToMiniCart(product) {
this.selectSize(product.size);
this.selectColor(product.color);
this.selectQuantity(product.originalQuantity);
this.addToCart();
},
viewCart() {
I.click(this.locators.miniCartIcon);
I.waitForElement(this.locators.cartHeader);
},
clickCopyLink() {
I.waitForEnabled(this.locators.copyLink);
I.click(this.locators.copyLink);
},
filterProductColor(color) {
I.waitForElement(this.locators.filterColor + color);
I.click(this.locators.filterColor + color);
},
filterProductSize(filterSizeTotal) {
let locator = locate(this.locators.filterSize)
.withAttr({ 'aria-hidden': 'true' })
.withText(filterSizeTotal);
I.waitForElement(locator);
I.click(locator);
},
filterProductPrice(filterPriceTotal) {
let locator = locate(this.locators.filterPrice)
.withAttr({ 'aria-hidden': 'true' })
.withText(filterPriceTotal);
I.waitForElement(locator);
I.click(locator);
},
filterProductOption(filterOption, firstProductName) {
let locatorOption = locate(this.locators.filterOption)
.withAttr({ 'aria-label': 'Sort By' });
I.waitForElement(locatorOption);
I.scrollTo(locatorOption);
I.selectOption(locatorOption, filterOption);
I.wait(1.5);
let locatorProduct = locate(this.locators.filterPDP).first();
I.waitForElement(locatorProduct);
I.see(firstProductName, locatorProduct);
},
clickMoreButton() {
I.click(this.locators.moreButton);
I.wait(1.5);
},
clickFirstTile() {
I.click(this.locators.firstProductTile)[0]; // eslint-disable-line no-unused-expressions
},
simulateBackButton() {
I.wait(1.5);
I.waitForElement(this.locators.pdpClass);
I.executeScript('window.history.back();');
I.wait(1.5);
I.waitNumberOfVisibleElements(this.locators.firstProductTile, 24);
},
verifyProductTotals(totalItems) {
let locator = locate(this.locators.productTotals)
.find(this.locators.filterPrice);
I.waitForElement(locator);
I.see(totalItems, locator);
},
openProductQuickView(pdpQuickViewLink) {
let locator = locate(this.locators.qv_ProductBtn)
.withAttr({ href: pdpQuickViewLink });
I.waitForElement(locator);
I.scrollTo(locator);
I.click(locator);
},
selectQuickViewColor(color) {
let locator = locate(this.locators.qv_ColorBtn)
.withAttr({ 'aria-label': 'Select Color ' + color });
I.waitForElement(locator);
I.click(locator);
},
selectQuickViewSize(size) {
I.waitForElement(this.locators.qv_SizeSelect);
I.selectOption(this.locators.qv_SizeSelect, size);
},
addToCartQuickView() {
I.waitForElement(this.locators.qv_AddToCart);
I.click(this.locators.qv_AddToCart);
},
clickCheckoutBtnOnMiniCart() {
I.waitForElement(this.locators.miniCartCheckoutButton);
I.click(this.locators.miniCartCheckoutButton);
}
};

View File

@@ -0,0 +1,10 @@
const { data, accountPage } = inject();
Then('shopper clicks add new address', () => {
accountPage.clickAddAddress();
});
Then('shopper fills out address information', () => {
accountPage.addAddress(data.account.addressTitle, data.checkout.fName, data.checkout.lName, data.checkout.address1,
data.checkout.country, data.checkout.state, data.checkout.city, data.checkout.zip, data.login.phone);
});

View File

@@ -0,0 +1,17 @@
const { data, accountPage } = inject();
Then('shopper clicks add new payment', () => {
accountPage.clickAddPayment();
});
Then('shopper fills out their payment information', () => {
accountPage.addPayment(data.account.name, data.checkout.ccNum, data.checkout.expMonth, data.checkout.expYear);
});
Then('shopper clicks view payments', () => {
accountPage.viewAllPayments();
});
Then('shopper removes a saved credit card', () => {
accountPage.removePayment(data.account.deletePaymentModalText);
});

View File

@@ -0,0 +1,9 @@
const { data, accountPage } = inject();
Then('shopper clicks edit password', () => {
accountPage.clickEditPassword();
});
Then('shopper changes their password', () => {
accountPage.changePassword(data.login.password, data.account.newPassword);
});

View File

@@ -0,0 +1,9 @@
const { data, accountPage } = inject();
Then('shopper clicks edit profile', () => {
accountPage.clickEditProfile();
});
Then('shopper edits phone number', () => {
accountPage.editProfile(data.login.phone, data.login.email, data.login.password);
});

View File

@@ -0,0 +1,10 @@
const { cartPage, productPage, data } = inject();
Then('shopper edits products in cart', () => {
productPage.viewCart();
cartPage.verifyCartQuantity(+data.product.quantity + +data.product2.quantity);
cartPage.removeProduct(data.product2.name);
cartPage.verifyCart(data.product.quantity, data.product.itemPrice, data.product.totalItemPrice,
data.product.shipping, data.product.tax, data.product.estimatedTotal);
cartPage.editQuantity(data.product.editCartQuantity);
});

View File

@@ -0,0 +1,56 @@
const { I, data, homePage, productPage, cartPage, checkoutPage } = inject();
let product;
Given('Shopper searches for {string}', (inputProduct) => {
product = inputProduct;
homePage.search(product);
});
When('selects size {string}', (size) => {
productPage.selectSize(size);
});
When('shopper changes product quantity', () => {
productPage.selectQuantity(data.product.quantity);
});
When('he adds the product to cart', async () => {
I.wait(1);
productPage.addToCart();
});
Then('he is able to see the correct product in cart', () => {
productPage.viewCart();
I.see(product, cartPage.locators.lineItemName);
cartPage.verifyCart(data.product.quantity, data.product.itemPrice, data.product.totalItemPrice,
data.product.shipping, data.product.tax, data.product.estimatedTotal);
});
When('shopper is able to add and remove a product from minicart', () => {
homePage.search(data.product4.searchWord);
productPage.addProductToMiniCart(data.product4);
cartPage.removeProductFromMiniCart(data.product4);
I.see(data.product4.afterRemoveQuantity, cartPage.locators.miniCartQuantity);
});
Then('shopper is able to add a product and edit product quantity in minicart', () => {
homePage.search(data.product4.searchWord);
productPage.addProductToMiniCart(data.product4);
cartPage.verifyMiniCartOriginal(data.product4);
cartPage.editMiniCartQuantity(data.product4);
cartPage.verifyMiniCartUpdated(data.product4);
});
Then('shopper is able to navigate through minicart, registered checkout pages and remove the product from cart', () => {
productPage.clickCheckoutBtnOnMiniCart();
let locator = locate(checkoutPage.locators.checkoutStage).withAttr({ 'data-customer-type': 'registered' });
I.seeElement(locator);
checkoutPage.gotoHomePageFromCheckout();
cartPage.removeProductFromMiniCart(data.product4);
I.see(data.product4.afterRemoveQuantity, cartPage.locators.miniCartQuantity);
});
Then('shopper goes to Guest Checkout page from minicart', () => {
productPage.clickCheckoutBtnOnMiniCart();
I.seeElement(checkoutPage.locators.checkoutAsGuestBtn);
});

View File

@@ -0,0 +1,12 @@
const { I, data, homePage } = inject();
Then('shopper enters email in signup form', () => {
I.scrollPageToBottom();
homePage.subscribeList(data.home.email);
});
Then('shopper subscribes to the email list', () => {
I.click(homePage.locators.subscribeButton);
I.waitForElement(homePage.locators.emailSignup);
I.see('Email Signup successful');
});

View File

@@ -0,0 +1,6 @@
const { I, data, homePage } = inject();
When('shopper selects yes or no for tracking consent', () => {
I.amOnPage(data.login.homePage);
homePage.accept();
});

View File

@@ -0,0 +1,15 @@
const { I, data, homePage } = inject();
Then('shopper goes to store locator page', () => {
I.amOnPage(data.storeLocator.pageURL);
});
Then('shopper searches for a store', () => {
homePage.searchForStore(data.storeLocator.zipCode);
homePage.verifyStoreResults(data.storeLocator.numStores);
});
Then('shopper searches for a store with different radius', () => {
homePage.changeStoreRadius(data.storeLocator.radius);
homePage.verifyStoreResults(data.storeLocator.numStoresRadius);
});

View File

@@ -0,0 +1,26 @@
const { I, data, loginPage } = inject();
Then('shopper is able to click tab to create account', () => {
I.click(loginPage.locators.createAccount);
});
Then('shopper is able fill out registration information with new email', () => {
loginPage.createAccount(data.login.fName, data.login.lName, data.login.phone, data.login.newRegEmail, data.login.password);
});
Then('shopper is able fill out registration information with existing email', () => {
loginPage.createAccount(data.login.fName, data.login.lName, data.login.phone, data.login.email, data.login.password);
});
Then('shopper is able to click the create account button', () => {
I.click(locate(loginPage.locators.primaryButton).withText('Create Account'));
// TODO If you see an error then we'll know it's good, but it's also good if you see a dashboard
});
Then('shopper sees a username is invalid error', () => {
I.see(data.login.registrationError);
});
Then('shopper does not see a username is invalid error', () => {
I.dontSee(data.login.registrationError);
});

View File

@@ -0,0 +1,14 @@
const { I, data, loginPage } = inject();
When('shopper clicks forgot password', () => {
I.waitForElement(loginPage.locators.forgotPassword);
I.click(loginPage.locators.forgotPassword);
});
When('shopper fills out their recovery email address', () => {
loginPage.forgotPassword(data.home.email);
});
Then('shopper should see request to change password prompt', () => {
loginPage.verifyPasswordReset();
});

View File

@@ -0,0 +1,43 @@
const { I, data, homePage, loginPage } = inject();
// For going to the login landing page
Given('shopper goes to the Login Page', () => {
I.amOnPage(data.login.homePage);
homePage.accept();
I.amOnPage(data.login.loginPage);
});
// For going to the login landing page and signing in
Then('shopper logs into the website', () => {
I.amOnPage(data.login.homePage);
homePage.accept();
I.amOnPage(data.login.loginPage);
loginPage.login(data.login.email, data.login.password);
});
Given('shopper logs into the website on phone', () => {
I.amOnPage(data.login.homePage);
homePage.accept();
I.seeElement(loginPage.locators.hamburgerLogin);
I.click(loginPage.locators.hamburgerLogin);
let locator = locate(loginPage.locators.loginBtn)
.withChild(loginPage.locators.loginBtnLink);
I.waitForElement(locator);
I.click(locator);
loginPage.login(data.login.email, data.login.password);
});
Given('shopper logs into the website on tablet', () => {
I.amOnPage(data.login.homePage);
homePage.accept();
let locator = locate(loginPage.locators.loginBtn)
.withChild(loginPage.locators.loginBtnLink);
I.waitForElement(locator);
I.click(locator);
loginPage.login(data.login.email, data.login.password);
});

View File

@@ -0,0 +1,23 @@
const { I, data, pageDesigner } = inject();
Then('shopper should see the campaign banner', () => {
I.waitForElement(pageDesigner.locators.campaignBanner);
I.seeElement(pageDesigner.locators.campaignBannerMessage);
});
Then('shopper should see the campaign banner message', () => {
I.see(data.pageDesigner.campaignBannerMessage, pageDesigner.locators.campaignBannerMessage);
});
Then('shopper should see a close button on campaign banner', () => {
I.seeElement(pageDesigner.locators.campaignBannerCloseButton);
});
Then('shopper should be able to close the campaign banner', () => {
I.click(pageDesigner.locators.campaignBannerCloseButton);
});
Then('shopper should no longer see the campaign banner', () => {
I.dontSeeElement(pageDesigner.locators.campaignBanner);
});

View File

@@ -0,0 +1,40 @@
const { data, pageDesigner } = inject();
When('Shopper sees the carousel {string}', (position) => {
var carouselPosition = position;
pageDesigner.seeCarousel(carouselPosition);
});
Given('Shopper sees carousel controls in carousel {string}', (position) => {
var carouselPosition = position;
pageDesigner.controlsVisible(carouselPosition);
});
Then('Shopper should see the next slide in the first carousel', () => {
pageDesigner.verifySlide(1, data.pageDesigner.mainBannerHeading2, pageDesigner.locators.mainBannerHeading);
});
When('Shopper clicks previous in carousel {string}', (position) => {
var carouselPosition = position;
pageDesigner.carouselControlClick(carouselPosition, pageDesigner.locators.carouselPrevious);
});
Then('Shopper should see the previous slide in the first carousel', () => {
pageDesigner.verifySlide(1, data.pageDesigner.mainBannerHeading, pageDesigner.locators.mainBannerHeading);
});
When('Shopper clicks next in carousel {string} {int} time(s)', (position, clicks) => {
var carouselPosition = position;
var carouselClicks = clicks;
for (var i = 0; i < carouselClicks; i++) {
pageDesigner.carouselControlClick(carouselPosition, pageDesigner.locators.carouselNext);
}
});
Then('Shopper should see next product in the second carousel', () => {
pageDesigner.verifySlide(2, data.pageDesigner.productTileProductName, '.product-name-link');
});
Then('Shopper should see previous slide in the second carousel', () => {
pageDesigner.verifySlide(2, data.pageDesigner.productTileProductName5, '.product-name-link');
});

View File

@@ -0,0 +1,16 @@
const { I, data, pageDesigner } = inject();
Then('shopper should see the category components', () => {
I.seeElement('.experience-commerce_assets-category .shop-category-label');
let el = locate('.experience-commerce_assets-category').at(1);
I.see(data.pageDesigner.category1, el);
I.see(data.pageDesigner.category2, el);
I.see(data.pageDesigner.category3, el);
I.see(data.pageDesigner.category4, el);
I.see(data.pageDesigner.category5, el);
});
Then('shopper can click on a category link', () => {
pageDesigner.clickPopulareCategory(1, '.shop-category-label', data.pageDesigner.categoryLink);
});

View File

@@ -0,0 +1,17 @@
const { I, data, pageDesigner, utilities } = inject();
Then('shopper should see the image and text component', () => {
I.waitForElement(pageDesigner.locators.ITC);
I.seeElement(pageDesigner.locators.ITC);
});
Then('shopper should see the overlay message', () => {
let ITCElement = locate(pageDesigner.locators.ITC).at(1);
let overlayText = ITCElement.find(pageDesigner.locators.ITCOverlay);
I.see(data.pageDesigner.imageAndTextOverlayText, overlayText);
});
Then('shopper should go to new arrivals page clicking on the image', () => {
utilities.clickToLoadPage(pageDesigner.locators.ITCImageLink, data.pageDesigner.imageAndTextNewArrival);
});

View File

@@ -0,0 +1,19 @@
const { I, data, pageDesigner, utilities } = inject();
Then('shopper should see the main banner', () => {
I.waitForElement(pageDesigner.locators.mainBanner);
I.seeElement(pageDesigner.locators.mainBanner);
});
Then('shopper should see the main banner message', () => {
let mainBannerElement = locate(pageDesigner.locators.mainBanner).at(1);
let heading = mainBannerElement.find(pageDesigner.locators.mainBannerHeading);
let subHeading = mainBannerElement.find(pageDesigner.locators.mainBannerSubHeading);
I.see(data.pageDesigner.mainBannerHeading, heading);
I.see(data.pageDesigner.mainBannerSubHeading, subHeading);
});
Then('shopper should go to womens clothing dresses clicking on the main banner', () => {
utilities.clickToLoadPage(pageDesigner.locators.mainBannerLink, data.pageDesigner.mainBannerLink);
});

View File

@@ -0,0 +1,6 @@
const { I, pageDesigner } = inject();
Then('shopper should see the photo tile component', () => {
I.waitForElement(pageDesigner.locators.photo);
I.seeElement(pageDesigner.locators.photo);
});

View File

@@ -0,0 +1,25 @@
const { I, pageDesigner } = inject();
Then('shopper should see the popularCategories layout', () => {
I.waitForElement('.popular-categories');
I.seeElement('.popular-categories .popular-cat-heading');
I.see('Popular Catalogs', '.popular-cat-heading h3');
I.seeElement('.popular-categories .popular-category');
});
Then('shopper should see the popularCategory components', () => {
I.seeNumberOfElements('.popular-category', 6);
let el = locate('.popular-cat-link').at(1);
I.see('Outfits', el);
I.see('Tops', el);
I.see('Dresses', el);
I.see('Bottoms', el);
I.see('Jackets & Coats', el);
I.see('Feeling Red', el);
});
Then('shopper can click on a popular category', () => {
pageDesigner.clickPopulareCategory(1, '.popular-category', '/s/RefArch/new arrivals/womens/?lang=default');
});

View File

@@ -0,0 +1,42 @@
const { I, data, pageDesigner, utilities } = inject();
Then('shopper should see the product tile component', () => {
I.seeElement(pageDesigner.locators.productTile1);
});
Then('shopper should see the alt attribute on product image', () => {
I.seeAttributesOnElements(pageDesigner.locators.productTile1Image, { alt: 'Floral Print Pencil Skirt.' });
});
Then('shopper should see the title attribute on product image', () => {
I.seeAttributesOnElements(pageDesigner.locators.productTile1Image, { title: 'Floral Print Pencil Skirt., ' });
});
Then('shopper should not see quickview on product tile', () => {
I.dontSeeElement(pageDesigner.locators.productTile1Quickview);
});
Then('shopper should see the product name on product tile', () => {
I.see(data.pageDesigner.productTileProductName, pageDesigner.locators.productTile1ProductName);
});
Then('shopper should see the regular price on product tile', () => {
I.see(data.pageDesigner.productTile1ProductPrice, pageDesigner.locators.productTile1ProductPrice);
});
Then('shopper should see the strike-through price on product tile', () => {
I.see(data.pageDesigner.productTile3ProductStrikeThroughPrice, pageDesigner.locators.productTile3StrikeThroughPrice);
});
Then('shopper should see the sales price on product tile', () => {
I.see(data.pageDesigner.productTile3ProductPrice, pageDesigner.locators.productTile3ProductPrice);
});
Then('shopper should go to the product details page clicking on the image', () => {
utilities.clickToLoadPage(pageDesigner.locators.productTile1ImageLinkToPdp, data.pageDesigner.productTile1PDPLink);
});
Then('shopper should go to the product details page clicking on product name', () => {
utilities.clickToLoadPage(pageDesigner.locators.productTile1NameLinkToPdp, data.pageDesigner.productTile1PDPLink);
});

View File

@@ -0,0 +1,12 @@
const { I, data, pageDesigner } = inject();
Then('shopper should see the rich text component', () => {
I.waitForElement(pageDesigner.locators.richText);
I.seeElement(pageDesigner.locators.richText);
});
Then('shopper should see the title', () => {
let richTextElement = locate(pageDesigner.locators.richText).at(1);
let title = richTextElement.find(pageDesigner.locators.richTextTitle);
I.see(data.pageDesigner.richTextTitle, title);
});

View File

@@ -0,0 +1,18 @@
const { I, data, pageDesigner, utilities } = inject();
Then('shopper should see the shop category heading', () => {
I.see(data.pageDesigner.shopCategoryTitle, pageDesigner.locators.shopCategoryHeading);
});
Then('shopper should see 5 shop categories', () => {
I.seeNumberOfElements(pageDesigner.locators.shopCategoryLabel, 5);
I.see(data.pageDesigner.shopCategory1, pageDesigner.locators.shopCategoryLink1);
I.see(data.pageDesigner.shopCategory2, pageDesigner.locators.shopCategoryLink2);
I.see(data.pageDesigner.shopCategory3, pageDesigner.locators.shopCategoryLink3);
I.see(data.pageDesigner.shopCategory4, pageDesigner.locators.shopCategoryLink4);
I.see(data.pageDesigner.shopCategory5, pageDesigner.locators.shopCategoryLink5);
});
Then('shopper should go to the category page by clicking on the category link', () => {
utilities.clickToLoadPage(pageDesigner.locators.shopCategoryLink3, data.pageDesigner.shopCategoryLink);
});

View File

@@ -0,0 +1,20 @@
const { I, data, pageDesigner } = inject();
Then('shopper should see the shop the look component', () => {
I.waitForElement(pageDesigner.locators.shopTheLookContainer);
I.seeElement(pageDesigner.locators.shopTheLookContainer);
});
Then('shopper should see the title when hover over image', () => {
I.moveCursorTo(pageDesigner.locators.shopTheLookImage);
I.see(data.pageDesigner.shopTheLookOverlayText, pageDesigner.locators.shopTheLookOverlayText);
I.see(data.pageDesigner.shopTheLookSetItems, pageDesigner.locators.shopTheLookSetItems);
I.see(data.pageDesigner.shopTheLookButton, pageDesigner.locators.shopTheLookButton);
});
Then('shopper should not see the setItem when hover over image on product', () => {
I.moveCursorTo(pageDesigner.locators.shopTheLook4thImage);
I.see(data.pageDesigner.shopTheLookProductName, pageDesigner.locators.shopTheLookProductName);
I.dontSeeElement(pageDesigner.locators.shopTheLook4thSetItems);
I.see(data.pageDesigner.shopTheLookButton, pageDesigner.locators.shopTheLook4thButton);
});

View File

@@ -0,0 +1,13 @@
const { productPage } = inject();
Then('shopper clicks on the more button', () => {
productPage.clickMoreButton();
});
Then('Shopper clicks on the first product Tile', () => {
productPage.clickFirstTile();
});
Then('Shopper clicks the back button on pdp', () => {
productPage.simulateBackButton();
});

View File

@@ -0,0 +1,24 @@
const { data, productPage, homePage } = inject();
Then('shopper searches for category from menu', () => {
homePage.searchMenu(data.searchPages.womensTops);
});
Then('shopper filters product by option', () => {
productPage.filterProductOption(data.filterProduct.option, data.filterProduct.productName);
});
Then('shopper filters product by color', () => {
productPage.filterProductColor(data.filterProduct.color);
productPage.verifyProductTotals(data.filterProduct.colorTotalItems);
});
Then('shopper filters product by size', () => {
productPage.filterProductSize(data.filterProduct.size);
productPage.verifyProductTotals(data.filterProduct.sizeTotalItems);
});
Then('shopper filters product by price', () => {
productPage.filterProductPrice(data.filterProduct.price);
productPage.verifyProductTotals(data.filterProduct.priceTotalItems);
});

View File

@@ -0,0 +1,12 @@
const { I, productPage, cartPage, data } = inject();
Then('shopper opens product quick view from home page', () => {
productPage.openProductQuickView(data.product3.productLinkQV);
});
Then('shopper adds to cart from Quick View', () => {
productPage.addToCartQuickView();
I.waitForVisible(productPage.locators.alertAddToCart);
productPage.viewCart();
cartPage.verifyCartQuantity(data.product3.quantity);
});

View File

@@ -0,0 +1,45 @@
const { I, homePage, productPage } = inject();
var should = require('should'); // eslint-disable-line
Given('shopper goes to the Product Detail Page', () => {
I.amOnPage('/on/demandware.store/Sites-RefArch-Site/en_US/Product-Show?pid=P0150M');
homePage.accept();
});
Then('shopper sees all the product related information', async () => {
(await I.grabAttributeFrom(productPage.locators.productImage, 'src'))[0].trim().should.containEql('P0150_001.jpg');
(await I.grabTextFrom(productPage.locators.productName))[0].trim().should.equal('Upright Case (33L - 3.7Kg)');
(await I.grabTextFrom(productPage.locators.productId)).trim().should.equal('P0150M');
(await I.grabTextFrom(productPage.locators.productAvailability)).trim().should.equal('In Stock');
(await I.grabTextFrom(productPage.locators.productPrice)).trim().should.equal('$99.99');
(await I.grabTextFrom(productPage.locators.productDescription)).trim().should.equal('This practical and functional case is perfect for business with no need to check in as luggage due to its cabin size dimensions or for any convenient no-fuss travel any time any where. You can pull along for comfort or carry by the handle, and with plenty of space inside and a large front pocket with additional zippered pocket, theres plenty of useful and compact storage.');
(await I.grabTextFrom(productPage.locators.productDetails)).trim().should.equal('1682 ballistic nylon and genuine leather inserts |Pull-out metallic handle for wheeling|Top and side handles|Cabin size for convenient travelling|TSA lock for security');
});
Then('shopper sees the correct breadcrumbs', async () => {
const breadcrumbsHrefs = await I.grabAttributeFrom(productPage.locators.navigationCrumbs, 'href');
breadcrumbsHrefs[0].should.containEql('mens'); // Mens Category
breadcrumbsHrefs[1].should.containEql('accessories'); // Accessories Category
breadcrumbsHrefs[2].should.containEql('luggage'); // Luggage Category
});
Then('shopper sees the correct social links', async () => {
I.seeElement(productPage.locators.pinterest); // Pinterest
I.seeElement(productPage.locators.facebook); // Facebook
I.seeElement(productPage.locators.twitter); // Twitter
I.seeElement(productPage.locators.copyLink); // Copy Link
const socialHrefs = await I.grabAttributeFrom(productPage.locators.socialShare, 'href');
socialHrefs[0].should.containEql('pinterest.com'); // Pinterest href
socialHrefs[1].should.containEql('facebook.com'); // Facebook href
socialHrefs[2].should.containEql('twitter.com'); // Twitter href
socialHrefs[3].should.containEql('copy-link-message'); // Copy Link href
});
Then('shopper is able to see Add to Cart Button Enabled', () => {
I.seeElement(productPage.locators.addToCartButtonEnabled);
});
Then('shopper is able to copy Product URL using Copy Link Icon', () => {
productPage.clickCopyLink();
I.seeElement(productPage.locators.copyLinkMsgVisible);
});

View File

@@ -0,0 +1,11 @@
const { I, homePage } = inject();
var should = require('should'); // eslint-disable-line
Given('shopper lands on the expected category landing page', () => {
I.amOnPage('/on/demandware.store/Sites-RefArch-Site/en_US/SourceCodeRedirect-Start?src=televisions4');
homePage.accept();
});
Then('shopper sees all the category landing page related information', async () => {
(await I.grabTextFrom('.page-title')).trim().should.equal('Flat Screen');
});

View File

@@ -0,0 +1,11 @@
const { I, homePage } = inject();
var should = require('should'); // eslint-disable-line
Given('shopper lands on the expected content page', () => {
I.amOnPage('/on/demandware.store/Sites-RefArch-Site/en_US/SourceCodeRedirect-Start?src=privacy3');
homePage.accept();
});
Then('shopper sees the expected content page', async () => {
(await I.grabTextFrom('.page-title')).trim().should.equal('Privacy Policy');
});

View File

@@ -0,0 +1,11 @@
const { I, homePage, productPage } = inject();
var should = require('should'); // eslint-disable-line
Given('shopper lands on the expected pdp', () => {
I.amOnPage('/on/demandware.store/Sites-RefArch-Site/en_US/SourceCodeRedirect-Start?src=ps3bundle5');
homePage.accept();
});
Then('shopper sees all the product related information v2', async () => {
(await I.grabTextFrom(productPage.locators.productName))[0].trim().should.equal('Playstation 3 Bundle');
});

View File

@@ -0,0 +1,90 @@
const { I, data, cartPage, checkoutPage, accountPage, loginPage } = inject();
var orderHistoryNumber = '';
Then('shopper goes to cart', () => {
I.waitForElement(cartPage.locators.cartIcon);
I.click(cartPage.locators.cartIcon);
});
Then('shopper changes product quantity to {string}', (quantity) => {
cartPage.editQuantity(quantity);
});
Then('shopper selects checkout from cart', () => {
I.waitForElement(cartPage.locators.checkoutBtn);
I.click(cartPage.locators.checkoutBtn);
});
Then('shopper selects checkout as guest', () => {
I.waitForElement(checkoutPage.locators.checkoutAsGuestBtn);
checkoutPage.fillPersonalDataGuest(data.checkout.email);
I.click(checkoutPage.locators.checkoutAsGuestBtn);
});
Then('shopper fills out shipping information', () => {
checkoutPage.fillShippingInfo(data.checkout.fName, data.checkout.lName, data.checkout.address1,
data.checkout.country, data.checkout.state, data.checkout.city,
data.checkout.zip, data.checkout.phone);
});
Then('shopper verifies shipping information', () => {
checkoutPage.verifyShipping(data.checkout.fName, data.checkout.lName, data.checkout.address1,
data.checkout.city, data.checkout.stateAbr, data.checkout.zip);
});
Then('shopper proceeds to payment section', () => {
I.waitForElement(checkoutPage.locators.toPayment);
I.click(checkoutPage.locators.toPayment);
});
Then('shopper fills out billing information', () => {
checkoutPage.fillPaymentInfoGuest(data.user1.fName, data.user1.lName, data.user1.address1,
data.user1.city, data.user1.stateAbr, data.user1.zip, data.checkout.phone, data.checkout.ccNum,
data.checkout.expMonth, data.checkout.expYear, data.checkout.ccSecCode);
});
Then('shopper fills out registered user billing information', () => {
checkoutPage.fillPaymentInfoRegistered(data.checkout.phone, data.checkout.ccSecCode);
});
Then('shopper places order', () => {
I.waitForElement(checkoutPage.locators.placeOrder);
I.click(checkoutPage.locators.placeOrder);
checkoutPage.verifyCheckoutInfo(data.checkout.fName, data.checkout.lName, data.checkout.address1,
data.checkout.city, data.checkout.zip, data.checkout.phone, data.checkout.ccNum, data.checkout.ccExpDate, data.product.quantity,
data.product.totalItemPrice, data.product.shipping, data.product.tax, data.product.estimatedTotal);
I.waitForElement(checkoutPage.locators.confirmOrder);
I.click(checkoutPage.locators.confirmOrder);
});
Then('shopper verifies the order confirmation page', async () => {
checkoutPage.verifyOrderConfirmation(data.checkout.fName, data.checkout.lName, data.checkout.address1,
data.checkout.city, data.checkout.zip, data.checkout.phone,
data.checkout.email, data.checkout.ccNum, data.checkout.ccExpDate, data.product.quantity,
data.product.totalItemPrice, data.product.shipping, data.product.tax, data.product.estimatedTotal);
orderHistoryNumber = await I.grabTextFrom('.summary-details.order-number');
});
Then('shopper goes to profile saved payments page and deletes credit card', () => {
I.amOnPage(data.account.accountPage);
accountPage.viewAllPayments();
accountPage.removePayment(data.account.deletePaymentModalText);
});
Then('logs out of the account', () => {
accountPage.logOut();
});
Then('shopper is able to fill out the order number, email, and zip code', () => {
loginPage.checkOrder(orderHistoryNumber, data.orderHistory.email, data.orderHistory.zip);
});
Then('shopper is able to click the check status button', () => {
I.waitForElement(loginPage.locators.primaryButton);
I.click(locate(loginPage.locators.primaryButton).withText('Check status'));
});
Then('shopper is able to view order detail', () => {
loginPage.verifyOrderHistory(data.product);
});

View File

@@ -0,0 +1,13 @@
const { I, utilities } = inject();
When('shopper load Page Designer home page', () => {
I.amOnPage('/s/RefArch/homepage-example.html?lang=default');
});
When('shopper load Page Designer campaign page', () => {
I.amOnPage('/s/RefArch/campaign-example.html?lang=default');
});
When('shopper accept the Consent Tracking Modal', () => {
utilities.accept();
});

View File

@@ -0,0 +1,20 @@
const I = actor();
module.exports = {
locators: {
consentTrackModal: '.modal-content',
consentTrackAffirm: '.affirm.btn.btn-primary'
},
accept() {
I.waitForElement(this.locators.consentTrackModal);
within(this.locators.consentTrackModal, () => {
I.click(this.locators.consentTrackAffirm);
});
},
clickToLoadPage(elementSelector, expectedPageUrl) {
I.click(elementSelector);
I.wait(1);
I.seeCurrentUrlEquals(expectedPageUrl);
}
};