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,12 @@
{
"env": {
"mocha": true
},
"rules": {
"require-jsdoc": "off",
"max-len": "off",
"quote-props": "off",
"no-new": "off",
"valid-jsdoc": "off"
}
}

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);
}
};

View File

@@ -0,0 +1,59 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Choice Of Bonus Products: Show Bonus Products', function () {
this.timeout(45000);
var variantPid1 = '701642842675M'; // Long Center Seam Skirt
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
var showBonusProductsParams;
before(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: 1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200);
cookieString = cookieJar.getCookieString(myRequest.url);
var bodyAsJson = JSON.parse(response.body);
showBonusProductsParams = bodyAsJson.newBonusDiscountLineItem.showProductsUrlRuleBased.split('?')[1];
});
});
it('should get information on choice of bonus product', function () {
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Product-ShowBonusProducts?' + showBonusProductsParams;
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200);
var bodyAsJson = JSON.parse(response.body);
assert.isNotNull(bodyAsJson.renderedTemplate);
assert.isString(bodyAsJson.closeButtonText);
assert.isString(bodyAsJson.enterDialogMessage);
});
});
});

View File

@@ -0,0 +1,50 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Add bundles to cart', function () {
this.timeout(5000);
it('should be able to add a bundle to Cart', function () {
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var bundlePid = 'womens-jewelry-bundleM';
var qty = 1;
var childProducts = [
{ pid: '013742002836M' },
{ pid: '013742002805M' },
{ pid: '013742002799M' }
];
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: bundlePid,
childProducts: childProducts,
quantity: qty
};
return request(myRequest, function (error, response) {
var bodyAsJson = JSON.parse(response.body);
var cartItems = bodyAsJson.cart.items[0];
assert.equal(response.statusCode, 200, 'Expected Cart-AddProduct bundles statusCode to be 200.');
assert.equal(cartItems.productName, 'Turquoise Jewelry Bundle');
assert.equal(cartItems.productType, 'bundle');
assert.equal(cartItems.priceTotal.price, '$113.00');
assert.equal(cartItems.bundledProductLineItems[0].id, '013742002836M');
assert.equal(cartItems.bundledProductLineItems[0].productName, 'Turquoise and Gold Bracelet');
assert.equal(cartItems.bundledProductLineItems[1].id, '013742002805M');
assert.equal(cartItems.bundledProductLineItems[1].productName, 'Turquoise and Gold Necklace');
assert.equal(cartItems.bundledProductLineItems[2].id, '013742002799M');
assert.equal(cartItems.bundledProductLineItems[2].productName, 'Turquoise and Gold Hoop Earring');
});
});
});

View File

@@ -0,0 +1,88 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Remove bundle from product line item', function () {
this.timeout(50000);
var cookieJar = request.jar();
var UUID;
var bundlePid = 'womens-jewelry-bundleM';
var qty = 1;
var childProducts = [
{ pid: '013742002836M' },
{ pid: '013742002805M' },
{ pid: '013742002799M' }
];
var myRequest = {
url: config.baseUrl + '/Cart-AddProduct',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
form: {
pid: bundlePid,
childProducts: childProducts,
quantity: qty,
options: []
},
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
before(function () {
return request(myRequest, function (error, response) {
assert.equal(response.statusCode, 200, 'Expected Cart-AddProduct bundles statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
UUID = bodyAsJson.cart.items[0].UUID;
});
});
it('1. should be able to remove a bundle from product line item', function () {
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + bundlePid + '&uuid=' + UUID;
return request(myRequest)
.then(function (removedItemResponse) {
assert.equal(removedItemResponse.statusCode, 200, 'Expected removeProductLineItem call statusCode to be 200.');
var bodyAsJson = JSON.parse(removedItemResponse.body);
assert.equal(bodyAsJson.basket.resources.emptyCartMsg, 'Your Shopping Cart is Empty', 'actual response from removing bundles not are expected');
assert.equal(bodyAsJson.basket.resources.numberOfItems, '0 Items', 'should return 0 items in basket');
});
});
it('2. should return error if UUID does not match', function () {
var bogusUUID = UUID + '3';
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + bundlePid + '&uuid=' + bogusUUID;
return request(myRequest)
.then(function (removedItemResponse) {
assert.equal(removedItemResponse.statusCode, 500, 'Expected removeProductLineItem request to fail when UUID is incorrect.');
})
.catch(function (error) {
assert.equal(error.statusCode, 500, 'Expected statusCode to be 500 for removing product item with bogus UUID.');
var bodyAsJson = JSON.parse(error.response.body);
assert.equal(bodyAsJson.errorMessage,
'Unable to remove item from the cart. Please try again! If the issue continues please contact customer service.',
'Actual error message from removing product item with non-matching PID and UUID not as expected');
});
});
it('3. should return error if bundle does not exist in Cart', function () {
var bogusBundleId = 'mens-jewelry-bundle';
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + bogusBundleId + '&uuid=' + UUID;
return request(myRequest)
.then(function (removedItemResponse) {
assert.equal(removedItemResponse.statusCode, 500, 'Expected removeProductLineItem call to fail when UUID is incorrect.');
})
.catch(function (error) {
assert.equal(error.statusCode, 500, 'Expected statusCode to be 500 for removing product item with bogus pid.');
var bodyAsJson = JSON.parse(error.response.body);
assert.equal(bodyAsJson.errorMessage,
'Unable to remove item from the cart. Please try again! If the issue continues please contact customer service.',
'Actual error message from removing product item with non-matching PID and UUID not as expected');
});
});
});

View File

@@ -0,0 +1,379 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Cart: Selecting Shipping Methods', function () {
this.timeout(5000);
var variantPid1 = '740357440196M';
var qty1 = '1';
var variantPid2 = '013742335538M';
var qty2 = '1';
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
form: {},
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
var expectedResponseCommon = {
'action': 'Cart-SelectShippingMethod',
'numOfShipments': 1,
'shipments': [
{
'shippingMethods': [
{
'description': 'Order received within 7-10 business days',
'displayName': 'Ground',
'ID': '001',
'shippingCost': '$7.99',
'estimatedArrivalTime': '7-10 Business Days'
},
{
'description': 'Order received in 2 business days',
'displayName': '2-Day Express',
'ID': '002',
'shippingCost': '$11.99',
'estimatedArrivalTime': '2 Business Days'
},
{
'description': 'Order received the next business day',
'displayName': 'Overnight',
'ID': '003',
'shippingCost': '$19.99',
'estimatedArrivalTime': 'Next Day'
},
{
'description': 'Orders shipped outside continental US received in 2-3 business days',
'displayName': 'Express',
'ID': '012',
'shippingCost': '$22.99',
'estimatedArrivalTime': '2-3 Business Days'
},
{
'description': 'Order shipped by USPS received within 7-10 business days',
'displayName': 'USPS',
'ID': '021',
'shippingCost': '$7.99',
'estimatedArrivalTime': '7-10 Business Days'
}
]
}
]
};
before(function () {
// ----- adding product #1:
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
childProducts: [],
quantity: qty1
};
return request(myRequest)
.then(function () {
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- adding product #2, a different variant of same product 1:
.then(function () {
myRequest.form = {
pid: variantPid2,
childProducts: [],
quantity: qty2
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
});
});
it(' 1>. should set the shipping method to Overnight', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$166.94',
'totalTax': '$7.95',
'totalShippingCost': '$19.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '003'; // 003 = Overnight
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson, expectedResponseCommon, 'Actual response not as expected.');
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, shipMethodId);
});
});
it(' 2>. should set the shipping method to Ground', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$164.84',
'totalTax': '$7.85',
'totalShippingCost': '$17.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, shipMethodId);
});
});
it(' 3>. should set the shipping method to 2-Day Express', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$158.54',
'totalTax': '$7.55',
'totalShippingCost': '$11.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '002'; // 002 = 2-Day Express
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals, 'Actual response not as expected.');
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, shipMethodId);
});
});
it(' 4>. should set to default method Ground when shipping method is set to Store Pickup', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$145.95',
'totalTax': '$6.95',
'totalShippingCost': '$0.00',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '005'; // 005 = Store Pickup
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, shipMethodId);
});
});
it(' 5>. should set the shipping method to Express', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$170.09',
'totalTax': '$8.10',
'totalShippingCost': '$22.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '012'; // 012 = Express
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, shipMethodId);
});
});
it(' 6>. should set the shipping method to USPS', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$154.34',
'totalTax': '$7.35',
'totalShippingCost': '$7.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '021'; // 021 = USPS
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, shipMethodId);
});
});
it(' 7>. should default to default shipping method for method with excluded Products', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$164.84',
'totalTax': '$7.85',
'totalShippingCost': '$17.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '004'; // 004 = Super Saver, has excluded Products
var groundShipMethodId = '001';
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, groundShipMethodId);
});
});
it(' 8>. should default to default shipping method for non-exist method', function () {
var expectTotals = {
'subTotal': '$139.00',
'grandTotal': '$164.84',
'totalTax': '$7.85',
'totalShippingCost': '$17.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
};
var shipMethodId = '9999';
var groundShipMethodId = '001';
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.totals, expectTotals);
assert.equal(bodyAsJson.shipments[0].selectedShippingMethod, groundShipMethodId);
});
});
});

View File

@@ -0,0 +1,451 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Add Product Set to cart', function () {
this.timeout(5000);
it('should add all products in a product set', function () {
var cookieJar = request.jar();
var pidsObj = [
{
'pid': '726819487824M',
'qty': '1',
options: ''
},
{
'pid': '69309284M-2',
'qty': '1',
options: ''
},
{
'pid': '799927335059M',
'qty': '1',
options: ''
}
];
var pidsObjString = JSON.stringify(pidsObj);
var myRequest = {
url: config.baseUrl + '/Cart-AddProduct',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
form: {
pidsObj: pidsObjString
},
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200);
var bodyAsJson = JSON.parse(response.body);
var expectedResponse = {
'action': 'Cart-AddProduct',
'queryString': '',
'locale': 'en_US',
'quantityTotal': 3,
'message': 'Product added to cart',
'cart': {
'actionUrls': {
'removeProductLineItemUrl': '/on/demandware.store/Sites-RefArch-Site/en_US/Cart-RemoveProductLineItem',
'updateQuantityUrl': '/on/demandware.store/Sites-RefArch-Site/en_US/Cart-UpdateQuantity',
'selectShippingUrl': '/on/demandware.store/Sites-RefArch-Site/en_US/Cart-SelectShippingMethod',
'submitCouponCodeUrl': '/on/demandware.store/Sites-RefArch-Site/en_US/Cart-AddCoupon',
'removeCouponLineItem': '/on/demandware.store/Sites-RefArch-Site/en_US/Cart-RemoveCouponLineItem'
},
'numOfShipments': 1,
'totals': {
'subTotal': '$268.00',
'totalShippingCost': '$9.99',
'grandTotal': '$291.89',
'totalTax': '$13.90',
'orderLevelDiscountTotal': {
'value': 0,
'formatted': '$0.00'
},
'shippingLevelDiscountTotal': {
'value': 0,
'formatted': '$0.00'
},
'discounts': [],
'discountsHtml': '\n'
},
'shipments': [
{
'shippingMethods': [
{
'ID': '001',
'displayName': 'Ground',
'description': 'Order received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'default': true,
'shippingCost': '$9.99',
'selected': true
},
{
'ID': '002',
'displayName': '2-Day Express',
'description': 'Order received in 2 business days',
'estimatedArrivalTime': '2 Business Days',
'default': false,
'shippingCost': '$15.99',
'selected': false
},
{
'ID': '003',
'displayName': 'Overnight',
'description': 'Order received the next business day',
'estimatedArrivalTime': 'Next Day',
'default': false,
'shippingCost': '$21.99',
'selected': false
},
{
'ID': '012',
'displayName': 'Express',
'description': 'Orders shipped outside continental US received in 2-3 business days',
'estimatedArrivalTime': '2-3 Business Days',
'default': false,
'shippingCost': '$28.99',
'selected': false
},
{
'ID': '021',
'displayName': 'USPS',
'description': 'Order shipped by USPS received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'default': false,
'shippingCost': '$9.99',
'selected': false
}
],
'selectedShippingMethod': '001'
}
],
'approachingDiscounts': [],
'items': [
{
'id': '726819487824M',
'productName': 'Platinum V Neck Suit Dress',
'price': {
'sales': {
'value': 99,
'currency': 'USD',
'formatted': '$99.00'
},
'list': null
},
'productType': 'variant',
'images': {
'small': [
{
'alt': 'Platinum V Neck Suit Dress, Black, small',
'url': '/on/demandware.static/-/Sites-apparel-catalog/default/dw98d73d67/images/small/PG.821301999.JJDH0XX.PZ.jpg',
'title': 'Platinum V Neck Suit Dress, Black'
}
]
},
'rating': 2,
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Black',
'attributeId': 'color',
'id': 'color'
},
{
'displayName': 'Size',
'displayValue': '6',
'attributeId': 'size',
'id': 'size'
}
],
'quantityOptions': {
'minOrderQuantity': 1,
'maxOrderQuantity': 10
},
'priceTotal': {
'price': '$99.00',
'renderedPrice': '\n\n\n<div class="strike-through\nnon-adjusted-price"\n>\n null\n</div>\n<div class="pricing line-item-total-price-amount item-total-null">$99.00</div>\n\n'
},
'isBonusProductLineItem': false,
'isGift': false,
'UUID': '609a030b33812caaf9654ddc1e',
'quantity': 1,
'isOrderable': true,
'promotions': null,
'renderedPromotions': '',
'attributes': null,
'availability': {
'messages': [
'In Stock'
],
'inStockDate': null
},
'isAvailableForInStorePickup': false
},
{
'id': '69309284M-2',
'productName': 'Modern Striped Dress Shirt',
'price': {
'sales': {
'value': 135,
'currency': 'USD',
'formatted': '$135.00'
},
'list': null
},
'productType': 'variant',
'images': {
'small': [
{
'alt': 'Modern Striped Dress Shirt, Blue, small',
'url': '/on/demandware.static/-/Sites-apparel-catalog/default/dw30e81930/images/small/B0174514_GY9_0.jpg',
'title': 'Modern Striped Dress Shirt, Blue'
}
]
},
'rating': 0,
'variationAttributes': [
{
'displayName': 'color',
'displayValue': 'Blue',
'attributeId': 'color',
'id': 'color'
},
{
'displayName': 'size',
'displayValue': '15L',
'attributeId': 'size',
'id': 'size'
}
],
'quantityOptions': {
'minOrderQuantity': 1,
'maxOrderQuantity': 10
},
'priceTotal': {
'price': '$135.00',
'renderedPrice': '\n\n\n<div class="strike-through\nnon-adjusted-price"\n>\n null\n</div>\n<div class="pricing line-item-total-price-amount item-total-null">$135.00</div>\n\n'
},
'isBonusProductLineItem': false,
'isGift': false,
'UUID': '5f7095b9af2af2ba8a062a2586',
'quantity': 1,
'isOrderable': true,
'promotions': null,
'renderedPromotions': '',
'attributes': null,
'availability': {
'messages': [
'In Stock'
],
'inStockDate': null
},
'isAvailableForInStorePickup': false
},
{
'id': '799927335059M',
'productName': 'Classic Wrap',
'price': {
'sales': {
'value': 34,
'currency': 'USD',
'formatted': '$34.00'
},
'list': null
},
'productType': 'variant',
'images': {
'small': [
{
'alt': 'Classic Wrap, Ivory, small',
'url': '/on/demandware.static/-/Sites-apparel-catalog/default/dwd7013224/images/small/PG.W20766.IVORYXX.PZ.jpg',
'title': 'Classic Wrap, Ivory'
}
]
},
'rating': 4,
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Ivory',
'attributeId': 'color',
'id': 'color'
}
],
'quantityOptions': {
'minOrderQuantity': 1,
'maxOrderQuantity': 10
},
'priceTotal': {
'price': '$34.00',
'renderedPrice': '\n\n\n<div class="strike-through\nnon-adjusted-price"\n>\n null\n</div>\n<div class="pricing line-item-total-price-amount item-total-null">$34.00</div>\n\n'
},
'isBonusProductLineItem': false,
'isGift': false,
'UUID': 'fdb8c0e48d32acecfa239fb2df',
'quantity': 1,
'isOrderable': true,
'promotions': null,
'renderedPromotions': '',
'attributes': null,
'availability': {
'messages': [
'In Stock'
],
'inStockDate': null
},
'isAvailableForInStorePickup': false
}
],
'numItems': 3,
'resources': {
'numberOfItems': '3 Items',
'emptyCartMsg': 'Your Shopping Cart is Empty'
}
},
'error': false
};
function verifyShippingMethods(shipMethod, ExpectedShipMethod) {
assert.equal(shipMethod.description, ExpectedShipMethod.description);
assert.equal(shipMethod.displayName, ExpectedShipMethod.displayName);
assert.equal(shipMethod.ID, ExpectedShipMethod.ID);
assert.equal(shipMethod.estimatedArrivalTime, ExpectedShipMethod.estimatedArrivalTime);
assert.equal(shipMethod.isDefault, ExpectedShipMethod.isDefault);
assert.equal(shipMethod.isSelected, ExpectedShipMethod.isSelected);
assert.equal(shipMethod.shippingCost, ExpectedShipMethod.shippingCost);
}
// ----- Verify quantityTotal, message, action, queryString
assert.equal(bodyAsJson.quantityTotal, expectedResponse.quantityTotal);
assert.equal(bodyAsJson.message, expectedResponse.message);
assert.equal(bodyAsJson.action, expectedResponse.action);
// ----- Verify actionUrls
var actionUrls = bodyAsJson.cart.actionUrls;
var expectedActionUrls = expectedResponse.cart.actionUrls;
assert.equal(actionUrls.removeProductLineItemUrl, expectedActionUrls.removeProductLineItemUrl);
assert.equal(actionUrls.updateQuantityUrl, expectedActionUrls.updateQuantityUrl);
assert.equal(actionUrls.selectShippingUrl, expectedActionUrls.selectShippingUrl);
assert.equal(actionUrls.submitCouponCodeUrl, expectedActionUrls.submitCouponCodeUrl);
assert.equal(actionUrls.removeCouponLineItem, expectedActionUrls.removeCouponLineItem);
// ----- Verify approaching discounts
assert.lengthOf(bodyAsJson.cart.approachingDiscounts, 0);
// ----- Verify numOfShipments
assert.equal(bodyAsJson.cart.numOfShipments, expectedResponse.cart.numOfShipments);
// ----- Verify totals
var totals = bodyAsJson.cart.totals;
var expectedTotals = expectedResponse.cart.totals;
assert.equal(totals.subTotal, expectedTotals.subTotal);
assert.equal(totals.grandTotal, expectedTotals.grandTotal);
assert.equal(totals.totalTax, expectedTotals.totalTax);
assert.equal(totals.totalShippingCost, expectedTotals.totalShippingCost);
assert.equal(totals.orderLevelDiscountTotal.value, expectedTotals.orderLevelDiscountTotal.value);
assert.equal(totals.orderLevelDiscountTotal.formatted, expectedTotals.orderLevelDiscountTotal.formatted);
assert.equal(totals.shippingLevelDiscountTotal.value, expectedTotals.shippingLevelDiscountTotal.value);
assert.equal(totals.shippingLevelDiscountTotal.formatted, expectedTotals.shippingLevelDiscountTotal.formatted);
assert.lengthOf(totals.discounts, 0);
// ----- Verify Shipments
var shipMethods = bodyAsJson.cart.shipments[0].shippingMethods;
var ExpectedShipMethods = expectedResponse.cart.shipments[0].shippingMethods;
for (var i = 0; i < ExpectedShipMethods.length; i++) {
verifyShippingMethods(shipMethods[i], ExpectedShipMethods[i]);
}
assert.equal(bodyAsJson.cart.shipments[0].selectedShippingMethod, expectedResponse.cart.shipments[0].selectedShippingMethod);
// ----- Verify product line items in cart
assert.lengthOf(bodyAsJson.cart.items, 3);
// Verify items in cart - item 1
var expectedItem0 = {
id: '726819487824M',
productName: 'Platinum V Neck Suit Dress',
price:
{
sales: {
value: 99,
currency: 'USD',
formatted: '$99.00'
}
},
variationAttributes:
[{ displayName: 'Color',
displayValue: 'Black'
},
{ displayName: 'Size',
displayValue: '6'
}
]
};
assert.containSubset(bodyAsJson.cart.items[0], expectedItem0);
// Verify items in cart - item 2
var expectedItem1 = {
id: '69309284M-2',
productName: 'Modern Striped Dress Shirt',
price: {
sales: {
value: 135,
currency: 'USD'
}
},
variationAttributes:
[{
displayName: 'color',
displayValue: 'Blue'
},
{ displayName: 'size',
displayValue: '15L'
}
]
};
assert.containSubset(bodyAsJson.cart.items[1], expectedItem1);
// Verify items in cart - item 3
var expectedItem2 = {
id: '799927335059M',
productName: 'Classic Wrap',
price: {
sales: {
value: 34,
currency: 'USD'
}
},
variationAttributes:
[{ displayName: 'Color',
displayValue: 'Ivory'
}
],
quantity: 1
};
assert.containSubset(bodyAsJson.cart.items[2], expectedItem2);
// ----- Verify number of items
assert.equal(bodyAsJson.cart.numItems, expectedResponse.cart.numItems);
// ----- Verify resource
assert.equal(bodyAsJson.cart.resources.numberOfItems, expectedResponse.cart.resources.numberOfItems);
assert.equal(bodyAsJson.cart.resources.emptyCartMsg, expectedResponse.cart.resources.emptyCartMsg);
});
});
});

View File

@@ -0,0 +1,266 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Add Product variants to cart', function () {
this.timeout(5000);
it('should add variants of different and same products, returns total quantity of added items', function () {
var cookieJar = request.jar();
// The myRequest object will be reused through out this file. The 'jar' property will be set once.
// The 'url' property will be updated on every request to set the product ID (pid) and quantity.
// All other properties remained unchanged.
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
var totalQty;
var variantPid1 = '701643421084M';
var qty1 = 2;
var variantPid2 = '701642923459M';
var qty2 = 1;
var variantPid3 = '013742000252M';
var qty3 = 11;
var variantPid4 = '029407331258M';
var qty4 = 3;
var action = 'Cart-AddProduct';
var message = 'Product added to cart';
var addProd = '/Cart-AddProduct';
// ----- adding product #1:
totalQty = qty1;
myRequest.url = config.baseUrl + addProd;
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200);
var expectedResBody = {
'quantityTotal': totalQty,
'action': action,
'message': message
};
var bodyAsJson = JSON.parse(response.body);
assert.equal(bodyAsJson.quantityTotal, expectedResBody.quantityTotal);
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- adding product #2, a different variant of same product 1:
.then(function () {
totalQty += qty2;
myRequest.url = config.baseUrl + addProd;
myRequest.form = {
pid: variantPid2,
quantity: qty2
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// Handle response from request #2
.then(function (response2) {
assert.equal(response2.statusCode, 200);
var expectedResBody2 = {
'action': action,
'quantityTotal': totalQty,
'message': message
};
var bodyAsJson2 = JSON.parse(response2.body);
assert.equal(bodyAsJson2.quantityTotal, expectedResBody2.quantityTotal);
})
// ----- adding product #3:
.then(function () {
totalQty += qty3;
myRequest.url = config.baseUrl + addProd;
myRequest.form = {
pid: variantPid3,
quantity: qty3
};
return request(myRequest);
})
// Handle response from request #3
.then(function (response3) {
assert.equal(response3.statusCode, 200);
var expectedResBody3 = {
'action': action,
'quantityTotal': totalQty,
'message': message
};
var bodyAsJson3 = JSON.parse(response3.body);
assert.equal(bodyAsJson3.quantityTotal, expectedResBody3.quantityTotal);
})
// ----- adding product #4:
.then(function () {
totalQty += qty4;
myRequest.url = config.baseUrl + addProd;
myRequest.form = {
pid: variantPid4,
quantity: qty4
};
return request(myRequest);
})
// Handle response from request #4
.then(function (response4) {
assert.equal(response4.statusCode, 200);
var bodyAsJson = JSON.parse(response4.body);
var expectedTotal = {
'subTotal': '$381.97',
'grandTotal': '$527.06',
'totalTax': '$25.10',
'totalShippingCost': '$119.99'
};
var expectedShippingMethod = {
'selectedShippingMethod': '001',
'shippingMethods': [
{
'displayName': 'Ground',
'ID': '001',
'estimatedArrivalTime': '7-10 Business Days',
'default': true,
'selected': true,
'shippingCost': '$9.99'
}
]
};
var expectedItems0 = {
'id': variantPid1,
'price': {
'sales': {
'currency': 'USD',
'value': 24
}
},
'productType': 'variant',
'variationAttributes': [
{
'attributeId': 'color',
'id': 'color'
},
{
'attributeId': 'size',
'id': 'size'
}
],
'quantity': qty1
};
var expectedItems1 = {
'id': variantPid2,
'price': {
'sales': {
'currency': 'USD',
'value': 24
}
},
'productType': 'variant',
'variationAttributes': [
{
'attributeId': 'color',
'id': 'color'
},
{
'attributeId': 'size',
'id': 'size'
}
],
'quantity': qty2
};
var expectedItems2 = {
'id': variantPid3,
'price': {
'sales': {
'currency': 'USD',
'value': 20
}
},
'productType': 'variant',
'variationAttributes': [
{
'attributeId': 'color',
'id': 'color'
}
],
'quantity': qty3
};
var expectedItems3 = {
'id': variantPid4,
'price': {
'list': {
'currency': 'USD',
'value': 39.5
},
'sales': {
'currency': 'USD',
'value': 29.99
}
},
'productType': 'variant',
'variationAttributes': [
{
'attributeId': 'color',
'id': 'color'
}
],
'quantity': qty4
};
// ----- Verify quantityTotal, message, action
assert.equal(bodyAsJson.quantityTotal, totalQty);
assert.equal(bodyAsJson.message, message);
assert.equal(bodyAsJson.action, action);
// ----- Verify totals
assert.containSubset(bodyAsJson.cart.totals, expectedTotal);
// ----- Verify Shipments
assert.containSubset(bodyAsJson.cart.shipments[0], expectedShippingMethod);
// ----- Verify product line items in cart
assert.lengthOf(bodyAsJson.cart.items, 4);
// ----- Verify Product id, quantity and name in Cart
assert.containSubset(bodyAsJson.cart.items[0], expectedItems0);
assert.containSubset(bodyAsJson.cart.items[1], expectedItems1);
assert.containSubset(bodyAsJson.cart.items[2], expectedItems2);
assert.containSubset(bodyAsJson.cart.items[3], expectedItems3);
});
});
});

View File

@@ -0,0 +1,134 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Edit product bundle', function () {
this.timeout(45000);
var variantPid1 = 'womens-jewelry-bundleM'; // womens jewelry bundle
var qty1 = 1;
var newQty1;
var prodIdUuidMap = {};
var variantUuid1;
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
before(function () {
// ----- adding product #1:
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
// ----- select a shipping method. Need to have shipping method so that shipping cost, sales tax,
// and grand total can be calculated
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest);
})
// ----- Get UUID for each product line items
.then(function (response4) {
var bodyAsJson = JSON.parse(response4.body);
prodIdUuidMap[bodyAsJson.items[0].id] = bodyAsJson.items[0].UUID;
variantUuid1 = prodIdUuidMap[variantPid1];
});
});
it('should update the bundle quantity', function () {
newQty1 = 3;
var newTotalQty = newQty1;
var expectQty1 = newQty1;
var expectedUpdateRep = {
'action': 'Cart-EditProductLineItem',
'cartModel': {
'totals': {
'subTotal': '$339.00',
'grandTotal': '$397.94',
'totalTax': '$18.95',
'totalShippingCost': '$39.99'
},
'items': [
{
'id': variantPid1,
'productName': 'Turquoise Jewelry Bundle',
'productType': 'bundle',
'price': {
'sales': {
'currency': 'USD',
'value': 113,
'formatted': '$113.00',
'decimalPrice': '113.00'
},
'list': null
},
'availability': {
'messages': [
'2 Item(s) in Stock',
'1 item(s) are available for pre-order'
],
'inStockDate': null
},
'available': true,
'UUID': variantUuid1,
'quantity': expectQty1,
'priceTotal': {
'price': '$339.00'
}
}
],
'numItems': newTotalQty,
'locale': 'en_US',
'resources': {
'numberOfItems': newTotalQty + ' Items',
'emptyCartMsg': 'Your Shopping Cart is Empty'
}
},
'newProductId': variantPid1
};
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-EditProductLineItem';
myRequest.form = {
uuid: variantUuid1,
pid: variantPid1,
quantity: newQty1
};
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(updateRsp.body);
assert.containSubset(bodyAsJson.cartModel.totals, expectedUpdateRep.cartModel.totals);
assert.containSubset(bodyAsJson.cartModel.items, expectedUpdateRep.cartModel.items);
assert.equal(bodyAsJson.cartModel.numItems, expectedUpdateRep.cartModel.numItems);
assert.containSubset(bodyAsJson.cartModel.resources, expectedUpdateRep.cartModel.resources);
});
});
});

View File

@@ -0,0 +1,306 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Edit product variant', function () {
this.timeout(45000);
var variantPid1 = '701643421084M'; // 3/4 Sleeve V-Neck Top: icy mint, XS
var qty1 = 1;
var variantPid2 = '793775362380M'; // Striped Silk Tie: red, 29.99
var qty2 = 1;
var newQty1;
var prodIdUuidMap = {};
var variantUuid1;
var variantUuid2;
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
before(function () {
// ----- adding product #1:
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function () {
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- adding product #2
.then(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid2,
quantity: qty2
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// ----- select a shipping method. Need to have shipping method so that shipping cost, sales tax,
// and grand total can be calculated
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest);
})
// ----- Get UUID for each product line items
.then(function (response4) {
var bodyAsJson = JSON.parse(response4.body);
prodIdUuidMap[bodyAsJson.items[0].id] = bodyAsJson.items[0].UUID;
prodIdUuidMap[bodyAsJson.items[1].id] = bodyAsJson.items[1].UUID;
variantUuid1 = prodIdUuidMap[variantPid1];
variantUuid2 = prodIdUuidMap[variantPid2];
});
});
it('should update product line item 1 with the new variant and quantity', function () {
// edit attributes of product variant 1
newQty1 = 3;
var newTotalQty = newQty1 + qty2;
var expectQty1 = newQty1;
var expectQty2 = qty2;
var newVariantPid1 = '701642923541M'; // 3/4 Sleeve V-Neck Top: Grey Heather, S
var expectedUpdateRep = {
'action': 'Cart-EditProductLineItem',
'cartModel': {
'totals': {
'subTotal': '$101.99',
'grandTotal': '$115.48',
'totalTax': '$5.50',
'totalShippingCost': '$7.99'
},
'items': [
{
'id': newVariantPid1,
'productName': '3/4 Sleeve V-Neck Top',
'price': {
'sales': {
'currency': 'USD',
'value': 24,
'formatted': '$24.00',
'decimalPrice': '24.00'
}
},
'images': {
'small': [
{
'alt': '3/4 Sleeve V-Neck Top, Grey Heather, small',
'title': '3/4 Sleeve V-Neck Top, Grey Heather'
}
]
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Grey Heather',
'attributeId': 'color'
},
{
'displayName': 'Size',
'displayValue': 'S',
'attributeId': 'size'
}
],
'availability': {
'messages': [
'In Stock'
],
'inStockDate': null
},
'UUID': variantUuid1,
'quantity': expectQty1,
'priceTotal': {
'price': '$72.00'
}
},
{
'id': variantPid2,
'productName': 'Striped Silk Tie',
'price': {
'list': {
'currency': 'USD',
'value': 39.5,
'formatted': '$39.50',
'decimalPrice': '39.50'
},
'sales': {
'currency': 'USD',
'value': 29.99,
'formatted': '$29.99',
'decimalPrice': '29.99'
}
},
'images': {
'small': [
{
'alt': 'Striped Silk Tie, Red, small',
'title': 'Striped Silk Tie, Red'
}
]
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Red',
'attributeId': 'color'
}
],
'availability': {
'messages': [
'In Stock'
],
'inStockDate': null
},
'UUID': variantUuid2,
'quantity': expectQty2
}
],
'numItems': newTotalQty,
'locale': 'en_US',
'resources': {
'numberOfItems': newTotalQty + ' Items',
'emptyCartMsg': 'Your Shopping Cart is Empty'
}
},
'newProductId': newVariantPid1
};
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-EditProductLineItem';
myRequest.form = {
uuid: variantUuid1,
pid: newVariantPid1,
quantity: newQty1
};
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(updateRsp.body);
assert.containSubset(bodyAsJson.cartModel.totals, expectedUpdateRep.cartModel.totals);
assert.equal(bodyAsJson.cartModel.items.length, expectedUpdateRep.cartModel.items.length);
assert.containSubset(bodyAsJson.cartModel.items, expectedUpdateRep.cartModel.items);
assert.equal(bodyAsJson.cartModel.numItems, expectedUpdateRep.cartModel.numItems);
assert.containSubset(bodyAsJson.cartModel.resources, expectedUpdateRep.cartModel.resources);
// Verify path to image source
var prodImageSrc1 = bodyAsJson.cartModel.items[0].images.small[0].url;
var prodImageSrc2 = bodyAsJson.cartModel.items[1].images.small[0].url;
assert.isTrue(prodImageSrc1.endsWith('/images/small/PG.10221714.JJ908XX.PZ.jpg'));
assert.isTrue(prodImageSrc2.endsWith('/images/small/PG.949114314S.REDSI.PZ.jpg'));
assert.equal(bodyAsJson.newProductId, expectedUpdateRep.newProductId);
});
});
// notice the product line 1 has been updated in the above test
it('should update product line item 2 with new price', function () {
// edit product variant 2 to have different price variant
var expectQty2 = qty2;
var newVariantPid2 = '793775370033M'; // Striped Silk Tie: Turquoise, 23.99
var expectedUpdateRep = {
'action': 'Cart-EditProductLineItem',
'cartModel': {
'items': [
{
'id': newVariantPid2,
'productName': 'Striped Silk Tie',
'price': {
'list': {
'currency': 'USD',
'value': 39.5,
'formatted': '$39.50',
'decimalPrice': '39.50'
},
'sales': {
'currency': 'USD',
'value': 23.99,
'formatted': '$23.99',
'decimalPrice': '23.99'
}
},
'images': {
'small': [
{
'alt': 'Striped Silk Tie, Turquoise, small',
'title': 'Striped Silk Tie, Turquoise'
}
]
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Turquoise',
'attributeId': 'color'
}
],
'UUID': variantUuid2,
'quantity': expectQty2,
'appliedPromotions': [
{
'callOutMsg': 'Get 20% off of this tie.'
}
]
}
]
},
'newProductId': newVariantPid2
};
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-EditProductLineItem';
myRequest.form = {
uuid: variantUuid2,
pid: newVariantPid2,
quantity: qty2
};
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(updateRsp.body);
assert.containSubset(bodyAsJson.cartModel.items, expectedUpdateRep.cartModel.items);
assert.equal(bodyAsJson.newProductId, expectedUpdateRep.newProductId);
});
});
});

View File

@@ -0,0 +1,182 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Edit product variant for merging products', function () {
this.timeout(45000);
var variantPid1 = '701643421084M'; // 3/4 Sleeve V-Neck Top: icy mint, XS
var qty1 = 1;
var variantPid2 = '701643421060M'; // 3/4 Sleeve V-Neck Top: yellow, XS
var qty2 = 1;
var newQty1;
var prodIdUuidMap = {};
var variantUuid1;
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
before(function () {
// ----- adding product #1:
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function () {
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- adding product #2
.then(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid2,
quantity: qty2
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// ----- select a shipping method. Need to have shipping method so that shipping cost, sales tax,
// and grand total can be calculated
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest);
})
// ----- Get UUID for each product line items
.then(function (response4) {
var bodyAsJson = JSON.parse(response4.body);
prodIdUuidMap[bodyAsJson.items[0].id] = bodyAsJson.items[0].UUID;
prodIdUuidMap[bodyAsJson.items[1].id] = bodyAsJson.items[1].UUID;
variantUuid1 = prodIdUuidMap[variantPid1];
});
});
it('should merge product line items into 1 with the new variant and quantity value', function () {
// edit attributes of product variant 1
newQty1 = 4;
var newTotalQty = newQty1 + qty2;
var newVariantPid1 = '701643421060M'; // 3/4 Sleeve V-Neck Top: Yellow, S
var expectedUpdateRep = {
'action': 'Cart-EditProductLineItem',
'cartModel': {
'totals': {
'subTotal': '$120.00',
'grandTotal': '$134.39',
'totalTax': '$6.40',
'totalShippingCost': '$7.99'
},
'items': [
{
'id': newVariantPid1,
'productName': '3/4 Sleeve V-Neck Top',
'price': {
'sales': {
'currency': 'USD',
'value': 24,
'formatted': '$24.00',
'decimalPrice': '24.00'
}
},
'images': {
'small': [
{
'alt': '3/4 Sleeve V-Neck Top, Butter, small',
'title': '3/4 Sleeve V-Neck Top, Butter',
'url': '/on/demandware.static/-/Sites-apparel-m-catalog/default/dwdd28bd60/images/small/PG.10221714.JJ370XX.PZ.jpg'
}
]
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Butter',
'attributeId': 'color'
},
{
'displayName': 'Size',
'displayValue': 'XS',
'attributeId': 'size'
}
],
'availability': {
'messages': [
'In Stock'
],
'inStockDate': null
},
'UUID': variantUuid1,
'quantity': 5,
'priceTotal': {
'price': '$120.00'
}
}
],
'numItems': newTotalQty,
'locale': 'en_US',
'resources': {
'numberOfItems': newTotalQty + ' Items',
'emptyCartMsg': 'Your Shopping Cart is Empty'
}
},
'newProductId': newVariantPid1
};
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-EditProductLineItem';
myRequest.form = {
uuid: variantUuid1,
pid: newVariantPid1,
quantity: newQty1
};
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(updateRsp.body);
assert.containSubset(bodyAsJson.cartModel.totals, expectedUpdateRep.cartModel.totals);
assert.equal(bodyAsJson.cartModel.items.length, expectedUpdateRep.cartModel.items.length);
assert.equal(bodyAsJson.cartModel.items[0].id, variantPid2);
assert.equal(bodyAsJson.cartModel.items[0].productName, '3/4 Sleeve V-Neck Top');
assert.equal(bodyAsJson.cartModel.items[0].productType, 'variant');
// Verify path to image source
var prodImageSrc1 = bodyAsJson.cartModel.items[0].images.small[0].url;
assert.isTrue(prodImageSrc1.endsWith('/images/small/PG.10221714.JJ370XX.PZ.jpg'));
assert.equal(bodyAsJson.newProductId, expectedUpdateRep.newProductId);
});
});
});

View File

@@ -0,0 +1,60 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Cart: Get product variant in cart for edit', function () {
this.timeout(45000);
var variantPid1 = '701643421084M'; // 3/4 Sleeve V-Neck Top: icy mint, XS
var variantUuid1;
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
before(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: 1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200);
cookieString = cookieJar.getCookieString(myRequest.url);
var bodyAsJson = JSON.parse(response.body);
variantUuid1 = bodyAsJson.cart.items[0].UUID;
});
});
it('should get information on the specified product', function () {
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-GetProduct?uuid=' + variantUuid1;
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200);
var bodyAsJson = JSON.parse(response.body);
assert.isNotNull(bodyAsJson.renderedTemplate);
assert.isString(bodyAsJson.closeButtonText);
assert.isString(bodyAsJson.enterDialogMessage);
});
});
});

View File

@@ -0,0 +1,270 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Remove product variant from line item', function () {
this.timeout(50000);
var variantPid1 = '701643421084M';
var qty1 = 2;
var variantPid2 = '701642923459M';
var qty2 = 1;
var variantPid3 = '029407331258M';
var qty3 = 3;
var prodIdUuidMap = {};
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
before(function () {
// ----- adding product #1:
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function () {
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- adding product #2, a different variant of same product 1:
.then(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid2,
quantity: qty2
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// ----- adding product #3:
.then(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid3,
quantity: qty3
};
return request(myRequest);
})
// ----- select a shipping method. Need shipping method so that shipping cost, sales tax,
// and grand total can be calculated.
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest);
})
// ----- Get UUID for each product line items
.then(function (response4) {
var bodyAsJson = JSON.parse(response4.body);
prodIdUuidMap[bodyAsJson.items[0].id] = bodyAsJson.items[0].UUID;
prodIdUuidMap[bodyAsJson.items[1].id] = bodyAsJson.items[1].UUID;
prodIdUuidMap[bodyAsJson.items[2].id] = bodyAsJson.items[2].UUID;
});
});
it(' 1>. should remove line item', function () {
// removing product variant on line item 2
var variantUuid2 = prodIdUuidMap[variantPid2];
var expectedItems = {
'totals': {
'subTotal': '$137.97',
'totalShippingCost': '$7.99',
'grandTotal': '$153.26',
'totalTax': '$7.30'
},
'shipments': [
{
'shippingMethods': [
{
'ID': '001',
'displayName': 'Ground',
'shippingCost': '$7.99',
'selected': true
}
],
'selectedShippingMethod': '001'
}
],
'items': [
{
'productName': '3/4 Sleeve V-Neck Top',
'price': {
'sales': {
'value': 24,
'currency': 'USD'
}
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Icy Mint'
},
{
'displayName': 'Size',
'displayValue': 'XS'
}
],
'quantity': 2
},
{
'productName': 'Solid Silk Tie',
'price': {
'sales': {
'value': 29.99,
'currency': 'USD'
},
'list': {
'value': 39.5,
'currency': 'USD'
}
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Red'
}
],
'quantity': 3
}
]
};
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + variantPid2 + '&uuid=' + variantUuid2;
return request(myRequest)
.then(function (removedItemResponse) {
assert.equal(removedItemResponse.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(removedItemResponse.body);
assert.containSubset(bodyAsJson.basket, expectedItems, 'Actual response dose not contain expected expectedResponse.');
// Verify path to image source
var prodImageSrc1 = bodyAsJson.basket.items[0].images.small[0].url;
var prodImageSrc2 = bodyAsJson.basket.items[1].images.small[0].url;
assert.isTrue(prodImageSrc1.endsWith('/images/small/PG.10221714.JJ8UTXX.PZ.jpg'), 'product 1 item image: src not end with /images/small/PG.10221714.JJ8UTXX.PZ.jpg.');
assert.isTrue(prodImageSrc2.endsWith('/images/small/PG.949432114S.REDSI.PZ.jpg'), 'product 2 item image: src not end with /images/small/PG.949432114S.REDSI.PZ.jpg.');
});
});
it(' 2>. should return error if PID and UUID does not match', function () {
var variantUuid3 = prodIdUuidMap[variantPid3];
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + variantPid1 + '&uuid=' + variantUuid3;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 500, 'Expected request to fail when PID and UUID do not match.');
})
.catch(function (err) {
assert.equal(err.statusCode, 500, 'Expected statusCode to be 500 for removing product item with non-matching PID and UUID.');
var bodyAsJson = JSON.parse(err.response.body);
assert.equal(bodyAsJson.errorMessage,
'Unable to remove item from the cart. Please try again! If the issue continues please contact customer service.',
'Actual error message from removing product item with non-matching PID and UUID not as expected');
});
});
it(' 3>. should remove all line items', function () {
var expectedRemoveAllResp = {
'totals': {
'subTotal': '$0.00',
'grandTotal': '$0.00',
'totalTax': '$0.00',
'totalShippingCost': '$0.00'
},
'shipments': [
{
'selectedShippingMethod': '001',
'shippingMethods': [
{
'description': 'Order received within 7-10 business days',
'displayName': 'Ground',
'ID': '001',
'shippingCost': '$0.00',
'estimatedArrivalTime': '7-10 Business Days',
'default': true,
'selected': true
}
]
}
],
'numItems': 0,
'resources': {
'numberOfItems': '0 Items',
'emptyCartMsg': 'Your Shopping Cart is Empty'
}
};
var variantUuid1 = prodIdUuidMap[variantPid1];
var variantUuid3 = prodIdUuidMap[variantPid3];
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + variantPid1 + '&uuid=' + variantUuid1;
return request(myRequest)
.then(function () {
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + variantPid3 + '&uuid=' + variantUuid3;
return request(myRequest);
})
// Handle response
.then(function (response2) {
assert.equal(response2.statusCode, 200, 'Expected statusCode from remove all product line item to be 200.');
var bodyAsJson2 = JSON.parse(response2.body);
assert.containSubset(bodyAsJson2.basket, expectedRemoveAllResp, 'Actual response from removing all items does not contain expectedRemoveAllResp.');
});
});
it(' 4>. should return error if product does not exist in cart', function () {
var variantPidNotExist = '701643421084Mabc';
var variantUuidNotExist = '529f59ef63a0d238b8575c4f8fabc';
myRequest.url = config.baseUrl + '/Cart-RemoveProductLineItem?pid=' + variantPidNotExist + '&uuid=' + variantUuidNotExist;
return request(myRequest)
.then(function (response3) {
assert.equal(response3.statusCode, 500, 'Expected request to fail when product does not exist.');
})
.catch(function (err) {
assert.equal(err.statusCode, 500, 'Expected statusCode to be 500 for removing product item not in cart.');
var bodyAsJson = JSON.parse(err.response.body);
assert.equal(bodyAsJson.errorMessage,
'Unable to remove item from the cart. Please try again! If the issue continues please contact customer service.',
'Actual error message of removing non-existing product item not as expected');
});
});
});

View File

@@ -0,0 +1,239 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var jsonHelpers = require('../helpers/jsonUtils');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
describe('Update quantity for product variant', function () {
this.timeout(45000);
var variantPid1 = '701643421084M';
var qty1 = 2;
var variantPid2 = '701642923459M';
var qty2 = 1;
var variantPid3 = '029407331258M';
var qty3 = 3;
var prodIdUuidMap = {};
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
before(function () {
// ----- adding product #1:
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function () {
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- adding product #2, a different variant of same product 1:
.then(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid2,
quantity: qty2
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// ----- adding product #3:
.then(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid3,
quantity: qty3
};
return request(myRequest);
})
// ----- select a shipping method. Need to have shipping method so that shipping cost, sales tax,
// and grand total can be calculated
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
return request(myRequest);
})
// ----- Get UUID for each product line items
.then(function (response4) {
var bodyAsJson = JSON.parse(response4.body);
prodIdUuidMap[bodyAsJson.items[0].id] = bodyAsJson.items[0].UUID;
prodIdUuidMap[bodyAsJson.items[1].id] = bodyAsJson.items[1].UUID;
prodIdUuidMap[bodyAsJson.items[2].id] = bodyAsJson.items[2].UUID;
});
});
it('1. should update line item quantity', function () {
// updating quantity of poduct variant 2
var newQty2 = 5;
var newTotal = qty1 + newQty2 + qty3;
var expectQty1 = qty1;
var expectQty2 = newQty2;
var expectQty3 = qty3;
var variantUuid1 = prodIdUuidMap[variantPid1];
var variantUuid2 = prodIdUuidMap[variantPid2];
var variantUuid3 = prodIdUuidMap[variantPid3];
var expectedUpdateRep = {
'action': 'Cart-UpdateQuantity',
'totals': {
'subTotal': '$257.97',
'grandTotal': '$281.36',
'totalTax': '$13.40',
'totalShippingCost': '$9.99'
},
'items': [
{
'id': variantPid1,
'productName': '3/4 Sleeve V-Neck Top',
'price': {
'sales': {
'currency': 'USD',
'value': 24
}
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Icy Mint'
},
{
'displayName': 'Size',
'displayValue': 'XS'
}
],
'UUID': variantUuid1,
'quantity': expectQty1
},
{
'id': variantPid2,
'productName': '3/4 Sleeve V-Neck Top',
'price': {
'sales': {
'currency': 'USD',
'value': 24
}
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Butter'
},
{
'displayName': 'Size',
'displayValue': 'M'
}
],
'UUID': variantUuid2,
'quantity': expectQty2
},
{
'id': variantPid3,
'productName': 'Solid Silk Tie',
'price': {
'list': {
'currency': 'USD',
'value': 39.5
},
'sales': {
'currency': 'USD',
'value': 29.99
}
},
'variationAttributes': [
{
'displayName': 'Color',
'displayValue': 'Red'
}
],
'UUID': variantUuid3,
'quantity': expectQty3
}
],
'numItems': newTotal,
'locale': 'en_US',
'resources': {
'numberOfItems': newTotal + ' Items',
'emptyCartMsg': 'Your Shopping Cart is Empty'
}
};
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-UpdateQuantity?pid=' + variantPid2 + '&uuid=' + variantUuid2 + '&quantity=' + newQty2;
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = jsonHelpers.deleteProperties(JSON.parse(updateRsp.body), ['queryString']);
assert.containSubset(bodyAsJson, expectedUpdateRep, 'Actual response does not contain expectedUpdateRep.');
// Verify path to image source
var prodImageSrc1 = bodyAsJson.items[0].images.small[0].url;
var prodImageSrc2 = bodyAsJson.items[1].images.small[0].url;
var prodImageSrc3 = bodyAsJson.items[2].images.small[0].url;
assert.isTrue(prodImageSrc1.endsWith('/images/small/PG.10221714.JJ8UTXX.PZ.jpg'), 'product 1 item image: src not end with /images/small/PG.10221714.JJ8UTXX.PZ.jpg.');
assert.isTrue(prodImageSrc2.endsWith('/images/small/PG.10221714.JJ370XX.PZ.jpg'), 'product 2 item image: src not end with /images/small/PG.10221714.JJ370XX.PZ.jpg.');
assert.isTrue(prodImageSrc3.endsWith('/images/small/PG.949432114S.REDSI.PZ.jpg'), 'product 3 item image: src not end with /images/small/PG.949432114S.REDSI.PZ.jpg.');
});
});
it('2. should return error if update line item quantity is 0', function () {
var variantUuid1 = prodIdUuidMap[variantPid1];
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-UpdateQuantity?pid=' + variantPid1 + '&uuid=' + variantUuid1 + '&quantity=0';
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 500, 'Expected request to fail for quantity = 0.');
})
.catch(function (err) {
assert.equal(err.statusCode, 500, 'Expected statusCode to be 500 for 0 quantity.');
});
});
it('3. should return error if update line item quantity is negative', function () {
var variantUuid1 = prodIdUuidMap[variantPid1];
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-UpdateQuantity?pid=' + variantPid1 + '&uuid=' + variantUuid1 + '&quantity=-1';
return request(myRequest)
.then(function (updateRsp) {
assert.equal(updateRsp.statusCode, 500, 'Expected request to fail for negative quantity.');
})
.catch(function (err) {
assert.equal(err.statusCode, 500, 'Expected statusCode to be 500 for 0 quantity.');
});
});
});

View File

@@ -0,0 +1,113 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var chai = require('chai');
var chaiSubset = require('chai-subset');
var jsonHelpers = require('../helpers/jsonUtils');
chai.use(chaiSubset);
/**
* Test case:
* should be able to submit an order with billingForm
*/
describe('billingForm', function () {
this.timeout(5000);
describe('positive test', function () {
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
var cookieString;
var variantPid1 = '701643421084M';
var qty1 = 2;
var addProd = '/Cart-AddProduct';
// ----- Step 1 adding product to Cart
myRequest.url = config.baseUrl + addProd;
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (addToCartResponse) {
assert.equal(addToCartResponse.statusCode, 200, 'Expected add to Cart request statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
myRequest.url = config.baseUrl + '/CSRF-Generate';
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
// step2 : get cookies, Generate CSRF, then set cookies
return request(myRequest);
})
.then(function (csrfResponse) {
var csrfJsonResponse = JSON.parse(csrfResponse.body);
// step3 : submit billing request with token aquired in step 2
myRequest.url = config.baseUrl + '/CheckoutServices-SubmitPayment?' +
csrfJsonResponse.csrf.tokenName + '=' +
csrfJsonResponse.csrf.token;
myRequest.form = {
dwfrm_billing_shippingAddressUseAsBillingAddress: 'true',
dwfrm_billing_addressFields_firstName: 'John',
dwfrm_billing_addressFields_lastName: 'Smith',
dwfrm_billing_addressFields_address1: '10 main St',
dwfrm_billing_addressFields_address2: '',
dwfrm_billing_addressFields_country: 'us',
dwfrm_billing_addressFields_states_stateCode: 'MA',
dwfrm_billing_addressFields_city: 'burlington',
dwfrm_billing_addressFields_postalCode: '09876',
dwfrm_billing_paymentMethod: 'CREDIT_CARD',
dwfrm_billing_creditCardFields_cardType: 'Visa',
dwfrm_billing_creditCardFields_cardNumber: '4111111111111111',
dwfrm_billing_creditCardFields_expirationMonth: '2',
dwfrm_billing_creditCardFields_expirationYear: '2030.0',
dwfrm_billing_contactInfoFields_phone: '9786543213',
dwfrm_billing_creditCardFields_securityCode: '342'
};
var ExpectedResBody = {
locale: 'en_US',
address: {
firstName: { value: 'John' },
lastName: { value: 'Smith' },
address1: { value: '10 main St' },
address2: { value: null },
city: { value: 'burlington' },
stateCode: { value: 'MA' },
postalCode: { value: '09876' },
countryCode: { value: 'us' }
},
paymentMethod: { value: 'CREDIT_CARD', htmlName: 'CREDIT_CARD' },
phone: { value: '9786543213' },
error: true,
cartError: true,
fieldErrors: [],
serverErrors: [],
saveCard: false
};
return request(myRequest)
.then(function (response) {
var bodyAsJson = JSON.parse(response.body);
var strippedBody = jsonHelpers.deleteProperties(bodyAsJson, ['redirectUrl', 'action', 'queryString']);
assert.equal(response.statusCode, 200, 'Expected CheckoutServices-SubmitPayment statusCode to be 200.');
assert.containSubset(strippedBody.address, ExpectedResBody.address, 'Expecting actual response address to be equal match expected response address');
assert.isFalse(strippedBody.error);
assert.equal(strippedBody.paymentMethod.value, ExpectedResBody.paymentMethod.value);
assert.equal(strippedBody.phone.value, ExpectedResBody.phone.value);
});
});
});
});

View File

@@ -0,0 +1,777 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
var jsonHelpers = require('../helpers/jsonUtils');
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
/**
* Test cases :
* 1. ProductSurchargeCost : Add Jewelery to cart with MA should show surcharge cost
* 2. When shipping to AK state, should return 2 applicableShipping methods only
* 3. When shipping to MA state, should return 4 applicableShipping methods
* 3. When Cart has over $100 product, shipping cost should be more for the same shipping method as #3 case
* 4. When State 'State' = 'AA' and 'AE' and 'AP' should output UPS as a shipping method
*/
describe('Select different State in Shipping Form', function () {
this.timeout(5000);
describe('productSurchargeCost with below $100 order', function () {
var cookieJar = request.jar();
var cookie;
before(function () {
var qty1 = 1;
var variantPid1 = '013742000443M';
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
.then(function () {
cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
});
});
it('should add surcharge to the Ground Shipping cost for jewelery', function () {
var ExpectedResBody = {
'order': {
'totals': {
'subTotal': '$38.00',
'grandTotal': '$56.69',
'totalTax': '$2.70',
'totalShippingCost': '$15.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
},
'shipping': [
{
'applicableShippingMethods': [
{
'description': 'Order received within 7-10 business days',
'displayName': 'Ground',
'ID': '001',
'shippingCost': '$5.99',
'estimatedArrivalTime': '7-10 Business Days'
},
{
'description': 'Order received in 2 business days',
'displayName': '2-Day Express',
'ID': '002',
'shippingCost': '$9.99',
'estimatedArrivalTime': '2 Business Days'
},
{
'description': 'Order received the next business day',
'displayName': 'Overnight',
'ID': '003',
'shippingCost': '$15.99',
'estimatedArrivalTime': 'Next Day'
}
],
'shippingAddress': {
'ID': null,
'postalCode': '09876',
'stateCode': 'MA',
'firstName': null,
'lastName': null,
'address1': null,
'address2': null,
'city': null,
'phone': null
},
'selectedShippingMethod': {
'ID': '001',
'displayName': 'Ground',
'description': 'Order received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'shippingCost': '$5.99'
}
}
]
}
};
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar
};
myRequest.url = config.baseUrl + '/CheckoutShippingServices-UpdateShippingMethodsList';
myRequest.form = {
'stateCode': 'MA',
'postalCode': '09876'
};
return request(myRequest)
// Handle response from request
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'addressId', 'jobTitle', 'postBox', 'salutation', 'secondName', 'companyName', 'suffix', 'suite', 'title']);
assert.containSubset(bodyAsJson.order.totals, ExpectedResBody.order.totals, 'Actual response.totals not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].applicableShippingMethods, ExpectedResBody.order.shipping[0].applicableShippingMethods, 'applicableShippingMethods not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].shippingAddress, ExpectedResBody.order.shipping[0].shippingAddress, 'shippingAddress is not as expected');
assert.containSubset(actualRespBodyStripped.order.shipping[0].selectedShippingMethod, ExpectedResBody.order.shipping[0].selectedShippingMethod, 'selectedShippingMethod is not as expected');
});
});
});
describe('productSurchargeCost with over $100 order', function () {
var cookieJar = request.jar();
var cookie;
before(function () {
var qty1 = 3;
var variantPid1 = '013742000443M';
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
.then(function () {
cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
});
});
it('should add surcharge to the Ground Shipping cost for each jewelery item', function () {
var ExpectedResBody = {
'order': {
'totals': {
'subTotal': '$114.00',
'grandTotal': '$159.59',
'totalTax': '$7.60',
'totalShippingCost': '$37.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
},
'shipping': [
{
'applicableShippingMethods': [
{
'description': 'Order received within 7-10 business days',
'displayName': 'Ground',
'ID': '001',
'shippingCost': '$7.99',
'estimatedArrivalTime': '7-10 Business Days'
},
{
'description': 'Order received in 2 business days',
'displayName': '2-Day Express',
'ID': '002',
'shippingCost': '$11.99',
'estimatedArrivalTime': '2 Business Days'
},
{
'description': 'Order received the next business day',
'displayName': 'Overnight',
'ID': '003',
'shippingCost': '$19.99',
'estimatedArrivalTime': 'Next Day'
}
],
'shippingAddress': {
'ID': null,
'postalCode': '09876',
'stateCode': 'MA',
'firstName': null,
'lastName': null,
'address1': null,
'address2': null,
'city': null,
'phone': null
},
'selectedShippingMethod': {
'ID': '001',
'displayName': 'Ground',
'description': 'Order received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'shippingCost': '$7.99'
}
}
]
}
};
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/CheckoutShippingServices-UpdateShippingMethodsList';
myRequest.form = {
'stateCode': 'MA',
'postalCode': '09876'
};
return request(myRequest)
// Handle response from request
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'addressId', 'jobTitle', 'postBox', 'salutation', 'secondName', 'companyName', 'suffix', 'suite', 'title']);
assert.containSubset(bodyAsJson.order.totals, ExpectedResBody.order.totals, 'Actual response.totals not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].applicableShippingMethods, ExpectedResBody.order.shipping[0].applicableShippingMethods, 'applicableShippingMethods not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].shippingAddress, ExpectedResBody.order.shipping[0].shippingAddress, 'shippingAddress is not as expected');
assert.containSubset(actualRespBodyStripped.order.shipping[0].selectedShippingMethod, ExpectedResBody.order.shipping[0].selectedShippingMethod, 'selectedShippingMethod is not as expected');
});
});
});
describe('select state=AK in Shipping Form', function () {
var cookieJar = request.jar();
var cookie;
before(function () {
var qty1 = 1;
var variantPid1 = '708141677371M';
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
.then(function () {
cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
});
});
it('should return 1 applicableShippingMethods for AK state', function () {
var ExpectedResBody = {
'order': {
'totals': {
'subTotal': '$49.99',
'grandTotal': '$70.33',
'totalTax': '$3.35',
'totalShippingCost': '$16.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
},
'shipping': [
{
'applicableShippingMethods': [
{
'description': 'Orders shipped outside continental US received in 2-3 business days',
'displayName': 'Express',
'ID': '012',
'shippingCost': '$16.99',
'estimatedArrivalTime': '2-3 Business Days'
}
],
'shippingAddress': {
'ID': null,
'postalCode': '09876',
'stateCode': 'AK',
'firstName': null,
'lastName': null,
'address1': null,
'address2': null,
'city': null,
'phone': null
},
'selectedShippingMethod': {
'ID': '012',
'displayName': 'Express',
'description': 'Orders shipped outside continental US received in 2-3 business days',
'estimatedArrivalTime': '2-3 Business Days',
'shippingCost': '$16.99'
}
}
]
}
};
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar
};
myRequest.url = config.baseUrl + '/CheckoutShippingServices-UpdateShippingMethodsList';
myRequest.form = {
'stateCode': 'AK',
'postalCode': '09876'
};
return request(myRequest)
// Handle response from request
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'addressId', 'jobTitle', 'postBox', 'salutation', 'secondName', 'companyName', 'suffix', 'suite', 'title']);
assert.containSubset(bodyAsJson.order.totals, ExpectedResBody.order.totals, 'Actual response.totals not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].applicableShippingMethods, ExpectedResBody.order.shipping[0].applicableShippingMethods, 'applicableShippingMethods not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].shippingAddress, ExpectedResBody.order.shipping[0].shippingAddress, 'shippingAddress is not as expected');
assert.containSubset(actualRespBodyStripped.order.shipping[0].selectedShippingMethod, ExpectedResBody.order.shipping[0].selectedShippingMethod, 'selectedShippingMethod is not as expected');
});
});
});
describe('select state=MA in Shipping Form', function () {
var cookieJar = request.jar();
var cookie;
before(function () {
var qty1 = 1;
var variantPid1 = '708141677371M';
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
.then(function () {
cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
});
});
it('should return 3 applicableShippingMethods for MA state', function () {
var ExpectedResBody = {
'order': {
'totals': {
'subTotal': '$49.99',
'grandTotal': '$58.78',
'totalTax': '$2.80',
'totalShippingCost': '$5.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
},
'shipping': [
{
'applicableShippingMethods': [
{
'description': 'Order received within 7-10 business days',
'displayName': 'Ground',
'ID': '001',
'shippingCost': '$5.99',
'estimatedArrivalTime': '7-10 Business Days'
},
{
'description': 'Order received in 2 business days',
'displayName': '2-Day Express',
'ID': '002',
'shippingCost': '$9.99',
'estimatedArrivalTime': '2 Business Days'
},
{
'description': 'Order received the next business day',
'displayName': 'Overnight',
'ID': '003',
'shippingCost': '$15.99',
'estimatedArrivalTime': 'Next Day'
}
],
'shippingAddress': {
'ID': null,
'postalCode': '09876',
'stateCode': 'MA',
'firstName': null,
'lastName': null,
'address1': null,
'address2': null,
'city': null,
'phone': null
},
'selectedShippingMethod': {
'ID': '001',
'displayName': 'Ground',
'description': 'Order received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'shippingCost': '$5.99'
}
}
]
}
};
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/CheckoutShippingServices-UpdateShippingMethodsList';
myRequest.form = {
'stateCode': 'MA',
'postalCode': '09876'
};
return request(myRequest)
// Handle response from request
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
// var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'ID']);
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'addressId', 'jobTitle', 'postBox', 'salutation', 'secondName', 'companyName', 'suffix', 'suite', 'title']);
assert.containSubset(bodyAsJson.order.totals, ExpectedResBody.order.totals, 'Actual response.totals not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].applicableShippingMethods, ExpectedResBody.order.shipping[0].applicableShippingMethods, 'applicableShippingMethods not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].shippingAddress, ExpectedResBody.order.shipping[0].shippingAddress, 'shippingAddress is not as expected');
assert.containSubset(actualRespBodyStripped.order.shipping[0].selectedShippingMethod, ExpectedResBody.order.shipping[0].selectedShippingMethod, 'selectedShippingMethod is not as expected');
});
});
});
describe('select State=MA with more than $100 order in Shipping Form', function () {
var cookieJar = request.jar();
var cookie;
before(function () {
var qty1 = 3;
var variantPid1 = '708141677371M';
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
.then(function () {
cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
});
});
it('shipping cost should be increased for State=MA', function () {
var ExpectedResBody = {
'order': {
'totals': {
'subTotal': '$149.97',
'grandTotal': '$165.86',
'totalTax': '$7.90',
'totalShippingCost': '$7.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
},
'shipping': [
{
'applicableShippingMethods': [
{
'description': 'Order received within 7-10 business days',
'displayName': 'Ground',
'ID': '001',
'shippingCost': '$7.99',
'estimatedArrivalTime': '7-10 Business Days'
},
{
'description': 'Order received in 2 business days',
'displayName': '2-Day Express',
'ID': '002',
'shippingCost': '$11.99',
'estimatedArrivalTime': '2 Business Days'
},
{
'description': 'Order received the next business day',
'displayName': 'Overnight',
'ID': '003',
'shippingCost': '$19.99',
'estimatedArrivalTime': 'Next Day'
}
],
'shippingAddress': {
'ID': null,
'postalCode': '09876',
'stateCode': 'MA',
'firstName': null,
'lastName': null,
'address1': null,
'address2': null,
'city': null,
'phone': null
},
'selectedShippingMethod': {
'ID': '001',
'displayName': 'Ground',
'description': 'Order received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'shippingCost': '$7.99'
}
}
]
}
};
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/CheckoutShippingServices-UpdateShippingMethodsList';
myRequest.form = {
'stateCode': 'MA',
'postalCode': '09876'
};
return request(myRequest)
// Handle response from request
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'addressId', 'jobTitle', 'postBox', 'salutation', 'secondName', 'companyName', 'suffix', 'suite', 'title']);
assert.containSubset(bodyAsJson.order.totals, ExpectedResBody.order.totals, 'Actual response.totals not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].applicableShippingMethods, ExpectedResBody.order.shipping[0].applicableShippingMethods, 'applicableShippingMethods not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].shippingAddress, ExpectedResBody.order.shipping[0].shippingAddress, 'shippingAddress is not as expected');
assert.containSubset(actualRespBodyStripped.order.shipping[0].selectedShippingMethod, ExpectedResBody.order.shipping[0].selectedShippingMethod, 'selectedShippingMethod is not as expected');
});
});
});
describe('UPS as applicable shipping methods', function () {
var cookieJar = request.jar();
var cookie;
before(function () {
var qty1 = 1;
var variantPid1 = '708141677371M';
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantPid1,
quantity: qty1
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
.then(function () {
cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
});
});
it('should include UPS as an applicable shipping methods for AP state', function () {
var ExpectedResBody = {
'order': {
'totals': {
'subTotal': '$49.99',
'grandTotal': '$58.78',
'totalTax': '$2.80',
'totalShippingCost': '$5.99',
'orderLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'shippingLevelDiscountTotal': {
'formatted': '$0.00',
'value': 0
},
'discounts': [],
'discountsHtml': '\n'
},
'shipping': [
{
'applicableShippingMethods': [
{
'description': 'Order shipped by USPS received within 7-10 business days',
'displayName': 'USPS',
'ID': '021',
'shippingCost': '$5.99',
'estimatedArrivalTime': '7-10 Business Days'
}
],
'shippingAddress': {
'ID': null,
'postalCode': '09876',
'stateCode': 'AP',
'firstName': null,
'lastName': null,
'address1': null,
'address2': null,
'city': null,
'phone': null
},
'selectedShippingMethod': {
'ID': '021',
'displayName': 'USPS',
'description': 'Order shipped by USPS received within 7-10 business days',
'estimatedArrivalTime': '7-10 Business Days',
'shippingCost': '$5.99'
}
}
]
}
};
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/CheckoutShippingServices-UpdateShippingMethodsList';
myRequest.form = {
'stateCode': 'AP',
'postalCode': '09876'
};
return request(myRequest)
// Handle response from request
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['selected', 'default', 'countryCode', 'addressId', 'jobTitle', 'postBox', 'salutation', 'secondName', 'companyName', 'suffix', 'suite', 'title']);
assert.containSubset(bodyAsJson.order.totals, ExpectedResBody.order.totals, 'Actual response.totals not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].applicableShippingMethods, ExpectedResBody.order.shipping[0].applicableShippingMethods, 'applicableShippingMethods not as expected.');
assert.containSubset(actualRespBodyStripped.order.shipping[0].shippingAddress, ExpectedResBody.order.shipping[0].shippingAddress, 'shippingAddress is not as expected');
assert.containSubset(actualRespBodyStripped.order.shipping[0].selectedShippingMethod, ExpectedResBody.order.shipping[0].selectedShippingMethod, 'selectedShippingMethod is not as expected');
});
});
});
});

View File

@@ -0,0 +1,60 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('ContactUs-Subscribe', function () {
this.timeout(25000);
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/ContactUs-Subscribe';
it('should successfully subscribe to contact us with valid email', function () {
myRequest.form = {
contactFirstName: 'Jane',
contactLastName: 'Smith',
contactEmail: 'JaneSmith@abc.com',
contactTopic: 'OS',
contactComment: 'Where is my order?'
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected add coupon request statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.isTrue(bodyAsJson.success);
assert.equal(bodyAsJson.msg, 'Subscribe to contact us success');
});
});
it('should error on subscribe to contact us with invalid email', function () {
myRequest.form = {
contactFirstName: 'Jane',
contactLastName: 'Smith',
contactEmail: 'JaneSmith@abc',
contactTopic: 'OS',
contactComment: 'Where is my order?'
};
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected add coupon request statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.isTrue(bodyAsJson.error);
assert.equal(bodyAsJson.msg, 'Please provide a valid email Id');
});
});
});

View File

@@ -0,0 +1,76 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Shipping Level Coupon - add coupon', function () {
this.timeout(25000);
var variantId = '740357377119M';
var quantity = 5;
var couponCode = 'shipping';
var cookieJar = request.jar();
var cookieString;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantId,
quantity: quantity
};
before(function () {
// adding 5 products to Cart
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected add to Cart request statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
// select a shipping method in order to get cart content
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// get CSRF token
.then(function () {
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/CSRF-Generate';
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest)
.then(function (csrfResponse) {
var csrfJsonResponse = JSON.parse(csrfResponse.body);
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-AddCoupon?couponCode=' +
couponCode + '&' + csrfJsonResponse.csrf.tokenName + '=' +
csrfJsonResponse.csrf.token;
});
});
});
it('should return discounted total for shipping cost', function () {
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected add coupon request statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.equal(bodyAsJson.totals.shippingLevelDiscountTotal.value, 8, 'shippingLevelDiscountTotal.value should be 8');
assert.equal(bodyAsJson.totals.shippingLevelDiscountTotal.formatted, '$8.00', 'shippingLevelDiscountTotal.formatted should be $8.00');
assert.equal(bodyAsJson.totals.discounts[0].type, 'coupon', 'actual totals discounts type should be coupon');
assert.isTrue(bodyAsJson.totals.discounts[0].applied, 'actual totals discounts applied should be true');
assert.include(bodyAsJson.totals.discountsHtml, 'Spend 500 and receive 50% off shipping', 'actual promotion call out message is correct');
});
});
});

View File

@@ -0,0 +1,83 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Shipping Level Coupon - remove coupon', function () {
this.timeout(25000);
var variantId = '740357377119M';
var quantity = 5;
var couponCode = 'shipping';
var cookieJar = request.jar();
var cookieString;
var UUID;
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: variantId,
quantity: quantity
};
before(function () {
// ----- adding 5 products to Cart
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected add to Cart request statusCode to be 200.');
cookieString = cookieJar.getCookieString(myRequest.url);
})
// ----- select a shipping method in order to get cart content
.then(function () {
var shipMethodId = '001'; // 001 = Ground
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-SelectShippingMethod?methodID=' + shipMethodId;
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
.then(function () {
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/CSRF-Generate';
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest);
})
// ----- apply shipping level coupon
.then(function (csrfResponse) {
var csrfJsonResponse = JSON.parse(csrfResponse.body);
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-AddCoupon?couponCode=' + couponCode +
'&' + csrfJsonResponse.csrf.tokenName + '=' + csrfJsonResponse.csrf.token;
return request(myRequest);
})
// ----- Get UUID information
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected apply shipping level coupon request statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
UUID = bodyAsJson.totals.discounts[0].UUID;
});
});
it('should return non-discounted total after removal of shipping coupon', function () {
myRequest.url = config.baseUrl + '/Cart-RemoveCouponLineItem?code=' + couponCode + '&uuid=' + UUID;
return request(myRequest)
.then(function (response) {
assert.equal(response.statusCode, 200, 'Expected remove shipping level coupon request statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
assert.equal(bodyAsJson.totals.shippingLevelDiscountTotal.value, 0, 'shippingLevelDiscountTotal value is 0');
assert.equal(bodyAsJson.totals.grandTotal, '$594.29', 'grandTotal is $594.29');
assert.equal(bodyAsJson.totals.totalTax, '$28.30', 'totalTax is $528.30');
});
});
});

View File

@@ -0,0 +1,55 @@
var _ = require('lodash');
function jsonUtils() {}
/**
* Duplicate the source object and delete specified key(s) from the new object.
*
* @param {JSON} srcObj
* @param {String[]} keys
* @returns {Object} - A new object with key(s) removed
*/
jsonUtils.deleteProperties = function (srcObj, keys) {
var newObj = _.cloneDeep(srcObj);
jsonUtils.removeProps(newObj, keys);
return newObj;
};
/**
* Delete specified key(s) from the object.
*
* @param {JSON} obj
* @param {String[]} keys
*/
jsonUtils.removeProps = function (obj, keys) {
if (obj instanceof Array && obj[0] !== null) {
obj.forEach(function (item) {
jsonUtils.removeProps(item, keys);
});
} else if (typeof obj === 'object') {
Object.getOwnPropertyNames(obj).forEach(function (key) {
if (keys.indexOf(key) !== -1) {
delete obj[key]; // eslint-disable-line no-param-reassign
} else if (obj[key] != null) {
jsonUtils.removeProps(obj[key], keys);
}
});
}
};
/**
* Return pretty-print JSON string
*
* @param {JSON} obj
*/
jsonUtils.toPrettyString = function (obj) {
var prettyString;
if (obj) {
prettyString = JSON.stringify(obj, null, '\t');
}
return prettyString;
};
module.exports = jsonUtils;

View File

@@ -0,0 +1,18 @@
function urlUtils() {}
/**
* Strips auth basic authentication parameters - if set - and returns the url
*
* @param {String} url - Url string
* @returns {String}
*/
urlUtils.stripBasicAuth = function (url) {
var sfIndex = url.indexOf('storefront');
var atIndex = url.indexOf('@');
if (sfIndex > -1 && atIndex > -1) {
return url.slice(0, sfIndex) + url.slice(atIndex + 1, url.length);
}
return url;
};
module.exports = urlUtils;

View File

@@ -0,0 +1,13 @@
'use strict';
var getConfig = require('@tridnguyen/config');
var opts = Object.assign({}, getConfig({
baseUrl: 'https://' + global.baseUrl + '/on/demandware.store/Sites-RefArch-Site/en_US',
suite: '*',
reporter: 'spec',
timeout: 60000,
locale: 'x_default'
}, './config.json'));
module.exports = opts;

View File

@@ -0,0 +1,38 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Add one Simple Product with Options to Cart', function () {
this.timeout(5000);
it('should add a simple product with options to Cart', function () {
var pid = 'mitsubishi-wd-73736M';
var quantity = '1';
var options = [{ 'optionId': 'tvWarranty', 'selectedValueId': '001' }];
var optionsString = JSON.stringify(options);
var myRequest = {
url: config.baseUrl + '/Cart-AddProduct',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
form: {
pid: pid,
childProducts: [],
quantity: quantity,
options: optionsString
},
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
return request(myRequest, function (error, response) {
var bodyAsJson = JSON.parse(response.body);
assert.equal(response.statusCode, 200, 'Cart-AddProduct call should return statusCode of 200');
assert.equal(bodyAsJson.message, 'Product added to cart');
assert.equal(bodyAsJson.cart.items[0].options[0].displayName, 'Extended Warranty: 1 Year Warranty');
assert.equal(bodyAsJson.cart.totals.subTotal, '$2,299.98');
});
});
});

View File

@@ -0,0 +1,114 @@
var assert = require('chai').assert;
var request = require('request-promise');
var config = require('../it.config');
describe('Edit Product Options for an Option Product in Cart', function () {
this.timeout(45000);
var productpid = 'mitsubishi-wd-73736M';
var quantity = 1;
var options = [{ 'optionId': 'tvWarranty', 'selectedValueId': '001' }];
var optionsString = JSON.stringify(options);
var productuuid;
var cookieString;
var cookieJar = request.jar();
var myRequest = {
url: '',
method: 'POST',
rejectUnauthorized: false,
resolveWithFullResponse: true,
jar: cookieJar,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
before(function () {
myRequest.url = config.baseUrl + '/Cart-AddProduct';
myRequest.form = {
pid: productpid,
quantity: quantity,
options: optionsString
};
return request(myRequest).then(function (response) {
assert.equal(response.statusCode, 200);
cookieString = cookieJar.getCookieString(myRequest.url);
var bodyAsJson = JSON.parse(response.body);
productuuid = bodyAsJson.cart.items[0].UUID;
});
});
it('should get information including options on the specified product', function () {
myRequest.method = 'GET';
myRequest.url = config.baseUrl + '/Cart-GetProduct?uuid=' + productuuid;
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest).then(function (response) {
assert.equal(response.statusCode, 200);
var bodyAsJson = JSON.parse(response.body);
assert.isNotNull(bodyAsJson.renderedTemplate);
assert.isString(bodyAsJson.closeButtonText);
assert.isString(bodyAsJson.enterDialogMessage);
assert.equal(bodyAsJson.product.options[0].selectedValueId, '001');
assert.equal(bodyAsJson.selectedOptionValueId, '001');
assert.equal(bodyAsJson.selectedQuantity, 1);
});
});
it('should edit options of the specified product', function () {
var newSelectedOptionValueId = '003';
var expectedResp = {
'action': 'Cart-EditProductLineItem',
'cartModel': {
'items': [
{
'id': productpid,
'productName': 'Mitsubishi 735 Series 73" DLP® High Definition Television',
'productType': 'optionProduct',
'price': {
'sales': {
'value': 2379.98,
'currency': 'USD',
'formatted': '$2,379.98',
'decimalPrice': '2379.98'
},
'list': null
},
'quantity': quantity,
'options': [
{
'displayName': 'Extended Warranty: 5 Year Warranty',
'optionId': 'tvWarranty',
'selectedValueId': newSelectedOptionValueId
}
]
}
]
},
'newProductId': productpid
};
myRequest.method = 'POST';
myRequest.url = config.baseUrl + '/Cart-EditProductLineItem';
myRequest.form = {
uuid: productuuid,
pid: productpid,
quantity: quantity,
selectedOptionValueId: newSelectedOptionValueId
};
var cookie = request.cookie(cookieString);
cookieJar.setCookie(cookie, myRequest.url);
return request(myRequest).then(function (response) {
assert.equal(response.statusCode, 200);
var bodyAsJson = JSON.parse(response.body);
assert.containSubset(bodyAsJson.cartModel, expectedResp.cartModel);
});
});
});

View File

@@ -0,0 +1,138 @@
var assert = require('chai').assert;
var request = require('request');
var config = require('../it.config');
var jsonHelpers = require('../helpers/jsonUtils');
var urlHelpers = require('../helpers/urlUtils');
describe('ProductVariation - Get product variation with only main product ID', function () {
this.timeout(5000);
var mainPid = '25604455M';
var myGetRequest = {
url: '',
method: 'GET',
rejectUnauthorized: false,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
it('should returns main product details and variant attributes', function (done) {
var resourcePath = config.baseUrl + '/Product-Variation?';
myGetRequest.url = resourcePath + 'pid=' + mainPid;
request(myGetRequest, function (error, response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
// Remove basic auth - to use intergration tests on test instances
var bodyAsJson = JSON.parse(response.body);
// strip out all "url" properties from the actual response
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['url', 'resetUrl', 'selectedProductUrl', 'raw', 'absURL']);
// Verify product
assert.equal(actualRespBodyStripped.product.productName, 'No-Iron Textured Dress Shirt');
assert.equal(actualRespBodyStripped.product.productType, 'master');
assert.equal(actualRespBodyStripped.product.id, mainPid);
assert.equal(actualRespBodyStripped.product.longDescription, 'This cotton dress shirt is available in white or blue. Both colors are a wardrobe necessity.');
// Verify product price
assert.equal(actualRespBodyStripped.product.price.sales.value, '49.99');
assert.equal(actualRespBodyStripped.product.price.sales.currency, 'USD');
assert.equal(actualRespBodyStripped.product.price.sales.formatted, '$49.99');
assert.equal(actualRespBodyStripped.product.price.list.value, '69.5');
assert.equal(actualRespBodyStripped.product.price.list.currency, 'USD');
assert.equal(actualRespBodyStripped.product.price.list.formatted, '$69.50');
// Verifying the following for product.variationAttributes of color swatch color= SLABLFB
var attrColorBlue = bodyAsJson.product.variationAttributes[0].values[0];
// Verify color swatch
assert.equal(attrColorBlue.value, 'SLABLFB');
assert.isTrue(bodyAsJson.product.variationAttributes[0].swatchable);
// Clean the resourcePath if basic auth is set
var resourcePathCleaned = urlHelpers.stripBasicAuth(resourcePath);
// Verify URL
assert.equal(attrColorBlue.url, resourcePathCleaned + 'dwvar_25604455M_color=SLABLFB&pid=25604455M&quantity=1', 'Actual color attribute = SLABLFB: url not as expected.');
// Verify Image
var colorBlueImages = attrColorBlue.images;
assert.isTrue(colorBlueImages.swatch[0].url.endsWith('SLABLFB.CP.jpg'), 'color SLABLFB image swatch[0]: url not ended with SLABLFB.CP.jpg.');
// Verify rating
assert.equal(bodyAsJson.product.rating, '3.3');
// Verify description
assert.equal(bodyAsJson.product.longDescription, 'This cotton dress shirt is available in white or blue. Both colors are a wardrobe necessity.');
assert.equal(bodyAsJson.product.shortDescription, 'This cotton dress shirt is available in white or blue. Both colors are a wardrobe necessity.');
// Verify availability
assert.equal(bodyAsJson.product.availability.messages, 'In Stock');
// Verifying the following for product.variationAttributes of color swatch color= WHITEFB
var attrColorWhite = bodyAsJson.product.variationAttributes[0].values[1];
// Verify color swatch
assert.equal(attrColorBlue.value, 'SLABLFB');
assert.equal(attrColorWhite.url, resourcePathCleaned + 'dwvar_25604455M_color=WHITEFB&pid=25604455M&quantity=1', 'Actual color attribute = WHITEFB: url not as expected.');
// Verify URL
var colorWhiteImages = attrColorWhite.images;
assert.isTrue(colorWhiteImages.swatch[0].url.endsWith('WHITEFB.CP.jpg'), 'color WHITEFB image swatch[0].url not ended with WHITEFB.CP.jpg.');
// Verify URL for product.variationAttributes of Size of id = 145
assert.equal(bodyAsJson.product.variationAttributes[1].values[0].url, resourcePathCleaned + 'dwvar_25604455M_size=145&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[0].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 150
assert.equal(bodyAsJson.product.variationAttributes[1].values[1].url, resourcePathCleaned + 'dwvar_25604455M_size=150&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[1].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 155
assert.equal(bodyAsJson.product.variationAttributes[1].values[2].url, resourcePathCleaned + 'dwvar_25604455M_size=155&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[2].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 160
assert.equal(bodyAsJson.product.variationAttributes[1].values[3].url, resourcePathCleaned + 'dwvar_25604455M_size=160&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[3].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 165
assert.equal(bodyAsJson.product.variationAttributes[1].values[4].url, resourcePathCleaned + 'dwvar_25604455M_size=165&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[4].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 170
assert.equal(bodyAsJson.product.variationAttributes[1].values[5].url, resourcePathCleaned + 'dwvar_25604455M_size=170&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[5].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 175
assert.equal(bodyAsJson.product.variationAttributes[1].values[6].url, resourcePathCleaned + 'dwvar_25604455M_size=175&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[6].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 180
assert.equal(bodyAsJson.product.variationAttributes[1].values[7].url, resourcePathCleaned + 'dwvar_25604455M_size=180&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[7].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 185
assert.equal(bodyAsJson.product.variationAttributes[1].values[8].url, resourcePathCleaned + 'dwvar_25604455M_size=185&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[8].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 190
assert.equal(bodyAsJson.product.variationAttributes[1].values[9].url, resourcePathCleaned + 'dwvar_25604455M_size=190&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[9].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 200
assert.equal(bodyAsJson.product.variationAttributes[1].values[10].url, resourcePathCleaned + 'dwvar_25604455M_size=200&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[10].url not as expected.');
// Verify URL for product.variationAttributes of Size of id = 220
assert.equal(bodyAsJson.product.variationAttributes[1].values[11].url, resourcePathCleaned + 'dwvar_25604455M_size=220&pid=25604455M&quantity=1', 'Actual product.variationAttributes[1].values[11].url not as expected.');
// Verify URL for product.variationAttributes of width = A (32/33)
assert.equal(bodyAsJson.product.variationAttributes[2].values[0].url, resourcePathCleaned + 'dwvar_25604455M_width=A&pid=25604455M&quantity=1', 'Actual product.variationAttributes[2].values[0].url not as expected.');
// Verify URL for product.variationAttributes of width = B (34/35)
assert.equal(bodyAsJson.product.variationAttributes[2].values[1].url, resourcePathCleaned + 'dwvar_25604455M_width=B&pid=25604455M&quantity=1', 'Actual product.variationAttributes[2].values[1].url not as expected.');
// Verify URL for product.variationAttributes of images
var prodImages = bodyAsJson.product.images;
assert.isTrue(prodImages.large[0].url.endsWith('WHITEFB.PZ.jpg'), 'product image large[0]: url not ended with WHITEFB.PZ.jpg');
assert.isTrue(prodImages.large[1].url.endsWith('WHITEFB.BZ.jpg'), 'product image large[1]: url not ended with WHITEFB.BZ.jpg');
assert.isTrue(prodImages.small[0].url.endsWith('WHITEFB.PZ.jpg'), 'product image small[0]: url not ended with WHITEFB.PZ.jpg');
assert.isTrue(prodImages.small[1].url.endsWith('WHITEFB.BZ.jpg'), 'product image small[1]: url not ended with WHITEFB.BZ.jpg');
done();
});
});
});

View File

@@ -0,0 +1,194 @@
var assert = require('chai').assert;
var request = require('request');
var _ = require('lodash');
var config = require('../it.config');
var jsonHelpers = require('../helpers/jsonUtils');
var urlHelpers = require('../helpers/urlUtils');
describe('ProductVariation - Get product variation with main product ID and all required variation attributes', function () {
this.timeout(5000);
var mainPid = '25604455M';
var paramColorWhite = 'dwvar_25604455M_color=WHITEFB';
var paramSize160 = 'dwvar_25604455M_size=160';
var paramWidth3233 = 'dwvar_25604455M_width=A';
var expectedVariant = '708141676220M';
var myGetRequest = {
url: '',
method: 'GET',
rejectUnauthorized: false,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
};
it('should returns variant for the selected attributes', function (done) {
var urlEndPoint = config.baseUrl + '/Product-Variation';
var urlWithMpid = urlEndPoint + '?pid=' + mainPid;
myGetRequest.url = urlWithMpid + '&' + paramColorWhite + '&' + paramSize160 + '&' + paramWidth3233;
request(myGetRequest, function (error, response) {
assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
var bodyAsJson = JSON.parse(response.body);
// strip out all "url" properties from the actual response
var actualRespBodyStripped = jsonHelpers.deleteProperties(bodyAsJson, ['url', 'resetUrl', 'selectedProductUrl', 'raw', 'absURL']);
var attrColor = actualRespBodyStripped.product.variationAttributes[0].values[0];
// Verify color swatch
assert.equal(attrColor.value, 'SLABLFB');
assert.isTrue(actualRespBodyStripped.product.variationAttributes[0].swatchable);
// Verify rating
assert.equal(actualRespBodyStripped.product.rating, '4.8');
// Verify description
assert.equal(actualRespBodyStripped.product.longDescription, 'This cotton dress shirt is available in white or blue. Both colors are a wardrobe necessity.');
assert.equal(actualRespBodyStripped.product.shortDescription, 'This cotton dress shirt is available in white or blue. Both colors are a wardrobe necessity.');
// Verify product
assert.equal(actualRespBodyStripped.product.productName, 'No-Iron Textured Dress Shirt');
assert.equal(actualRespBodyStripped.product.productType, 'variant');
assert.equal(actualRespBodyStripped.product.id, expectedVariant);
assert.equal(actualRespBodyStripped.product.longDescription, 'This cotton dress shirt is available in white or blue. Both colors are a wardrobe necessity.');
// Verify product price
assert.equal(actualRespBodyStripped.product.price.sales.value, '49.99');
assert.equal(actualRespBodyStripped.product.price.sales.currency, 'USD');
assert.equal(actualRespBodyStripped.product.price.sales.formatted, '$49.99');
assert.equal(actualRespBodyStripped.product.price.list.value, '69.5');
assert.equal(actualRespBodyStripped.product.price.list.currency, 'USD');
assert.equal(actualRespBodyStripped.product.price.list.formatted, '$69.50');
// Verify URL for product.variationAttributes of color = SLABLFB
var attrColorBlue = bodyAsJson.product.variationAttributes[0].values[0];
var urlSplit1 = attrColorBlue.url.split('?');
var urlParams = urlSplit1[1].split('&');
var urlEndPointCleaned = urlHelpers.stripBasicAuth(urlEndPoint);
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Color with id = SLABLFB: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Color with id = SLABLFB: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Color with id = SLABLFB: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Color with id = SLABLFB: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=SLABLFB'), 'product.variationAttributes Color with id = SLABLFB: url not include parameter dwvar_25604455M_color=SLABLFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=160'), 'product.variationAttributes Color with id = SLABLFB: url not include parameter dwvar_25604455M_size=160');
var colorBlueImages = attrColorBlue.images;
assert.isTrue(colorBlueImages.swatch[0].url.endsWith('SLABLFB.CP.jpg'), 'color SLABLFB image swatch[0]: url not ended with SLABLFB.CP.jpg.');
// Verify URL for product.variationAttributes of color = WHITEFB
var attrColorWhite = bodyAsJson.product.variationAttributes[0].values[1];
urlSplit1 = attrColorWhite.url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Color with id = WHITEFB: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Color with id = WHITEFB: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Color with id = WHITEFB: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Color with id = WHITEFB: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color='), 'product.variationAttributes Color with id = WHITEFB: url not include parameter dwvar_25604455M_color=');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=160'), 'product.variationAttributes Color with id = WHITEFB: url not include parameter dwvar_25604455M_size=160');
var colorWhiteImages = attrColorWhite.images;
assert.isTrue(colorWhiteImages.swatch[0].url.endsWith('WHITEFB.CP.jpg'), 'color WHITEFB image swatch[0]: url not ended with WHITEFB.CP.jpg.');
// Verify URL for product.variationAttributes Size with id = 145
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[0].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 145: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 145: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 145: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 145: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 145: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=145'), 'product.variationAttributes Size with id = 145: url not include parameter dwvar_25604455M_size=145');
// Verify URL for product.variationAttributes of Size of id = 150
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[1].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 150: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 150: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 150: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 150: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 150: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=150'), 'product.variationAttributes Size with id = 150: url not include parameter dwvar_25604455M_size=150');
// Verify URL for product.variationAttributes Size with id = 155
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[2].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 155: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 155: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 155: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 155: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 155: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=155'), 'product.variationAttributes Size with id = 155: url not include parameter dwvar_25604455M_size=155');
// Verify URL for product.variationAttributes Size with id = 160
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[3].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 160: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 160: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 160: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 160: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 160: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size='), 'product.variationAttributes Size with id = 160: url not include parameter dwvar_25604455M_size=');
// Verify URL for product.variationAttributes Size with id = 165
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[4].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 165: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 165 url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 165: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 165: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 165: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=165'), 'product.variationAttributes Size with id = 165: url not include parameter dwvar_25604455M_size=165');
// Verify URL for product.variationAttributes Size with id = 170
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[5].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 170: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 170 url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 170: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 170: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 170: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=170'), 'product.variationAttributes Size with id = 170: url not include parameter dwvar_25604455M_size=170');
// Verify URL for product.variationAttributes Size with id = 180
urlSplit1 = bodyAsJson.product.variationAttributes[1].values[7].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = 180: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = 180 url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = 180: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=A'), 'product.variationAttributes Size with id = 180: url not include parameter dwvar_25604455M_width=A');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = 180: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=180'), 'product.variationAttributes Size with id = 180: url not include parameter dwvar_25604455M_size=180');
// Verify URL for product.variationAttributes of width = A (32/33)
urlSplit1 = bodyAsJson.product.variationAttributes[2].values[0].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = A: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = A: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = A: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width='), 'product.variationAttributes Size with id = A: url not include parameter dwvar_25604455M_width=');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = A: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=160'), 'product.variationAttributes Size with id = A: url not include parameter dwvar_25604455M_size=160');
// Verify URL for product.variationAttributes of width = B (34/35)
urlSplit1 = bodyAsJson.product.variationAttributes[2].values[1].url.split('?');
urlParams = urlSplit1[1].split('&');
assert.equal(urlSplit1[0], urlEndPointCleaned, 'product.variationAttributes Size with id = B: actual request end point not equal expected value.');
assert.equal(urlParams.length, 5, 'product.variationAttributes Size with id = B: url does not have 5 parameters.');
assert.isTrue(_.includes(urlParams, 'pid=' + mainPid), 'product.variationAttributes Size with id = B: url not include parameter pid=' + mainPid);
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_width=B'), 'product.variationAttributes Size with id = B: url not include parameter dwvar_25604455M_width=B');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_color=WHITEFB'), 'product.variationAttributes Size with id = B: url not include parameter dwvar_25604455M_color=WHITEFB');
assert.isTrue(_.includes(urlParams, 'dwvar_25604455M_size=160'), 'product.variationAttributes Size with id = B: url not include parameter dwvar_25604455M_size=160');
// Verify URL for product.variationAttributes of images
var prodImages = bodyAsJson.product.images;
assert.isTrue(prodImages.large[0].url.endsWith('WHITEFB.PZ.jpg'), 'product image large[0]: url not ended with WHITEFB.PZ.jpg.');
assert.isTrue(prodImages.large[1].url.endsWith('WHITEFB.BZ.jpg'), 'product image large[1]: url not ended with WHITEFB.BZ.jpg.');
assert.isTrue(prodImages.small[0].url.endsWith('WHITEFB.PZ.jpg'), 'product image small[0]: url not ended with WHITEFB.PZ.jpg.');
assert.isTrue(prodImages.small[1].url.endsWith('WHITEFB.BZ.jpg'), 'product image small[1]: url not ended with WHITEFB.BZ.jpg.');
done();
});
});
});

Some files were not shown because too many files have changed in this diff Show More