Skip to content

Instantly share code, notes, and snippets.

@voboshi
Created Jul 24, 2020
Embed
What would you like to do?
// desktop.spec.js
// Line 8 would change between the three layouts.
import ProductListingPage from '../pages/plp.page'
describe('Desktop Viewport', () => {
beforeEach(() => {
cy.viewport(1200, 700)
cy.visit('/gridHackathonV1.html')
})
afterEach(() => {
cy.matchImageSnapshot()
})
it('should contain all needed page elements', function () {
ProductListingPage.validateHeaderElements(1, 'Desktop')
ProductListingPage.validateNavigationElements(1, 'Desktop')
ProductListingPage.validateMainContainer(1, 'Desktop')
ProductListingPage.validateFooter(1, 'Desktop')
})
})
// plp.page.js
// Note that I've removed the methods not used in the above snippet.
// The validations use a custom method as we needed to report results in a .txt file.
class ProductListingPage {
header = '#DIV__mainheader__3'
logo = '#logo'
mainMenu = '#DIV__mainmenu__15'
subMenu = '.submenu'
mainNavigation = '#DIV__mainnavinn__36'
searchInput = '#DIV__customsear__41'
headerTools = '#UL__toptools__46'
cartHeaderTool = '#DIV__dropdowndr__48'
wishListHeaderTool = '#A__wishlist__52'
profileHeaderTool = '#DIV__dropdowndr__55'
mobileSearchHeaderTool = '#A__btnsearchm__59'
mainContainer = '#DIV__containerm__65'
filtersColumn = '#filter_col'
filterLabels = 'label.container_check'
filterConfirmButton = '#filterBtn'
topBanner = '#DIV__topbanner__187'
plpToolbox = '#DIV__toolboxele__189'
toolboxSortDropdown = '#DIV__sortselect__193'
toolboxFilterButton = '#A__openfilter__206'
toolboxViewAsGrid = '#I__tiviewgrid__202'
toolboxViewAsList = '#I__tiviewlist__204'
productGrid = '#product_grid'
gridItem = '.grid_item'
productTitle = 'h3'
newPrice = '.new_price'
footer = 'footer'
footerContainer = '.col-lg-3.col-md-6'
footerSelector = '#UL__footersele__457'
footerAdditionalLinks = '#UL__additional__471'
validateHeaderElements(task, viewport) {
switch (viewport) {
case 'Desktop':
cy.get(this.header).within(() => {
cy.shouldBeVisible(
this.logo,
task,
'logo should be visible',
viewport
)
cy.shouldBeVisible(
this.mainMenu,
task,
'main menu should be visible',
viewport
)
cy.get(this.mainMenu)
.find(this.subMenu)
.should(($menuItems) => {
expect($menuItems).to.have.length(5)
})
})
break
case 'Tablet':
case 'Mobile':
cy.get(this.header).within(() => {
cy.shouldBeVisible(
this.logo,
task,
'logo should be visible',
viewport
)
cy.shouldNotBeVisible(
this.mainMenu,
task,
'main menu should not be visible',
viewport
)
})
}
}
validateNavigationElements(task, viewport) {
switch (viewport) {
case 'Desktop':
cy.get(this.mainNavigation).within(() => {
cy.shouldBeVisible(
this.searchInput,
task,
'search input should be visible',
viewport
)
cy.get(this.headerTools).within(() => {
cy.shouldBeVisible(
this.cartHeaderTool,
task,
'header cart icon should be visible',
viewport
)
cy.shouldBeVisible(
this.wishListHeaderTool,
task,
'header wishlist icon should be visible',
viewport
)
cy.shouldBeVisible(
this.profileHeaderTool,
task,
'header profile icon should be visible',
viewport
)
cy.shouldNotBeVisible(
this.mobileSearchHeaderTool,
task,
'mobile search icon should not be visible',
viewport
)
})
})
break
case 'Tablet':
cy.get(this.mainNavigation).within(() => {
cy.shouldBeVisible(
this.searchInput,
task,
'search input should be visible',
viewport
)
cy.get(this.headerTools).within(() => {
cy.shouldBeVisible(
this.cartHeaderTool,
task,
'header cart icon should be visible',
viewport
)
cy.shouldNotBeVisible(
this.wishListHeaderTool,
task,
'header wishlist icon should not be visible',
viewport
)
cy.shouldBeVisible(
this.profileHeaderTool,
task,
'header profile icon should be visible',
viewport
)
cy.shouldNotBeVisible(
this.mobileSearchHeaderTool,
task,
'mobile search icon should not be visible',
viewport
)
})
})
break
case 'Mobile':
cy.get(this.mainNavigation).within(() => {
cy.shouldNotBeVisible(
this.searchInput,
task,
'search input should not be visible',
viewport
)
cy.get(this.headerTools).within(() => {
cy.shouldBeVisible(
this.cartHeaderTool,
task,
'header cart icon should be visible',
viewport
)
cy.shouldNotBeVisible(
this.wishListHeaderTool,
task,
'header wishlist icon should not be visible',
viewport
)
cy.shouldBeVisible(
this.profileHeaderTool,
task,
'header profile icon should be visible',
viewport
)
cy.shouldBeVisible(
this.mobileSearchHeaderTool,
task,
'mobile search icon should be visible',
viewport
)
})
})
}
}
validateMainContainer(task, viewport) {
switch (viewport) {
case 'Desktop':
cy.get(this.mainContainer).within(() => {
cy.shouldBeVisible(
this.filtersColumn,
task,
'filters column should be visible',
viewport
)
cy.shouldBeVisible(
this.topBanner,
task,
'hero image should be visible',
viewport
)
cy.shouldBeVisible(
this.plpToolbox,
task,
'plp header should be visible',
viewport
)
cy.get(this.plpToolbox).within(() => {
cy.shouldBeVisible(
this.toolboxSortDropdown,
task,
'sort dropdown should be visible',
viewport
)
cy.shouldNotBeVisible(
this.toolboxFilterButton,
task,
'filter icon should not be visible',
viewport
)
cy.shouldBeVisible(
this.toolboxViewAsGrid,
task,
'view as grid icon should be visible',
viewport
)
cy.shouldBeVisible(
this.toolboxViewAsList,
task,
'view as list icon should be visible',
viewport
)
})
cy.shouldBeVisible(
this.productGrid,
task,
'product grid should be visible',
viewport
)
cy.get(this.productGrid)
.find(this.gridItem)
.each(($item, index, $list) => {
cy.get($item)
.find(this.productTitle)
.should('be.visible')
cy.get($item)
.find(this.newPrice)
.should('be.visible')
})
.then(($list) => {
expect($list).to.have.length.greaterThan(1)
})
})
break
case 'Tablet':
case 'Mobile':
cy.get(this.mainContainer).within(() => {
cy.shouldNotBeVisible(
this.filtersColumn,
task,
'filters column should not be visible',
viewport
)
cy.shouldBeVisible(
this.topBanner,
task,
'hero image should be visible',
viewport
)
cy.shouldBeVisible(
this.plpToolbox,
task,
'plp header should be visible',
viewport
)
cy.get(this.plpToolbox).within(() => {
cy.shouldBeVisible(
this.toolboxSortDropdown,
task,
'sort dropdown should be visible',
viewport
)
cy.shouldBeVisible(
this.toolboxFilterButton,
task,
'filter icon should be visible',
viewport
)
cy.shouldNotBeVisible(
this.toolboxViewAsGrid,
task,
'view as grid icon should not be visible',
viewport
)
cy.shouldNotBeVisible(
this.toolboxViewAsList,
task,
'view as list icon should not be visible',
viewport
)
})
cy.shouldBeVisible(
this.productGrid,
task,
'product grid should be visible',
viewport
)
cy.get(this.productGrid)
.find(this.gridItem)
.each(($item, index, $list) => {
cy.get($item)
.find(this.productTitle)
.should('be.visible')
cy.get($item)
.find(this.newPrice)
.should('be.visible')
})
.then(($list) => {
expect($list).to.have.length.greaterThan(1)
})
})
}
}
validateFooter(task, viewport) {
switch (viewport) {
case 'Desktop':
case 'Tablet':
case 'Mobile':
cy.get(this.footer).within(() => {
cy.get(this.footerContainer).should('have.length', 3)
cy.shouldBeVisible(
this.footerSelector,
task,
'footer selector should be visible',
viewport
)
cy.shouldBeVisible(
this.footerAdditionalLinks,
task,
'footer additional links should be visible',
viewport
)
})
}
}
}
export default new ProductListingPage()
// support/commands.js
// Contains the custom assertion methods, reporting to a .txt file and screenshot diff initialisation.
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'
addMatchImageSnapshotCommand({
capture: 'fullPage',
})
Cypress.Commands.add('shouldBeVisible', (element, task, testName, viewport) => {
var displayed = true
var device = ''
var width = 0
try {
cy.get(element).should('be.visible')
} catch (e) {
displayed = false
}
if (viewport == 'Desktop') {
device = 'Desktop'
width = 1200
} else if (viewport == 'Tablet') {
device = 'Tablet'
width = 768
} else if (viewport == 'Mobile') {
device = 'Mobile'
width = 500
}
return cy.reportToFile(task, testName, element, displayed, device, width)
})
Cypress.Commands.add(
'shouldNotBeVisible',
(element, task, testName, viewport) => {
var notDisplayed = true
var device = ''
var width = 0
try {
cy.get(element).should('not.be.visible')
} catch (e) {
notDisplayed = false
}
if (viewport == 'Desktop') {
device = 'Desktop'
width = 1200
} else if (viewport == 'Tablet') {
device = 'Tablet'
width = 768
} else if (viewport == 'Mobile') {
device = 'Mobile'
width = 500
}
return cy.reportToFile(
task,
testName,
element,
notDisplayed,
device,
width
)
}
)
Cypress.Commands.add(
'reportToFile',
(task, testName, domId, comparisonResult, device, width) => {
cy.writeFile(
'Traditional-V1-TestResults.txt',
`Task: ${task}, Test Name: ${testName}, DOM Id: ${domId}, Browser: ${
Cypress.browser.name
}, Viewport: ${width} x 700, Device: ${device}, Status: ${
comparisonResult ? 'Pass' : 'Fail'
}\n`,
{ flag: 'a+' }
)
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment