Cypress.io
When testing is easy, developers build better things faster and with confidence.
@bahmutov
Ask Questions at Sli.do
event code #cy-pendo
@georgepalf
Ask Questions at Sli.do
event code #cy-pendo
"Pendo combines powerful product usage analytics with user guidance, communication, feedback, and planning tools to offer the most complete integrated platform for digital product teams. With Pendo, product teams can understand product usage, collect feedback, measure sentiment, onboard users, and announce new features in app—all without requiring engineering resources."
Ask Questions at Sli.do event code #cy-pendo
Ask Questions at Sli.do
event code #cy-pendo
Guides provide personalised in-app guides and messaging
Highlight new features
User onboarding and tutorials
Polls & Surveys
Can be used to capture feedback on new products and features
Resource Center
Houses additional help for users including:
Guide activation - Automatic
Guide activation - Badge
Guide activation - Target Element
But how do we do this?..
Users launch the
Users can then create guides targeting their features and pages where required.
Visual Design Studio
over their application.
Visual Design Studio
Bonus point!
Who then go on to create...
Beautiful walkthroughs...
Stunning polls...
And delightful resource centers...
Stunning Polls...
And delightful Resource Centers...
Ask Questions at Sli.do
event code #cy-pendo
General pain points potentially leading to false starts using test automation frameworks...
Lack of maintenance and iterations
Flaky/unstable tests
Inconsistent test patterns - storing of web elements (with POM)
Lack of visibility of tests and results
Onboarding or prior knowledge required
Lack of team adoption
Lack of leadership buy in
Problem
Solution
Flaky/unstable tests
Cypress Retries
Inconsistent test patterns
Best practice of using data attributes
Static waits
Waiting on aliases and/or assertions
Lack of visibility
Cypress Dashboard
Onboarding or prior knowledge required
Front end tests with detailed documentation
Team adoption
Leadership buy in
Maintenance
Ask Questions at Sli.do
event code #cy-pendo
Sanity Suite
Regression Suite
Runs on all branches and blocks merge
Light touch of all areas
Full coverage of the Visual Design Studio
Tests are dependent on environment resources
Tests are independent and create their own resources and can be pointed at any environment
cypress/integration/sanity
cypress/integration/regression
Scheduled to run nightly on the release branch
1. Define test suite coverage...
3. Build the Sanity suite
4. Build the Regression suite
5. Document maintenance processes following Cypress best practices, leveraging Slack and Cypress Dashboard
2. Infrastructure setup and configuration
Ask Questions at Sli.do
event code #cy-pendo
Scheduled run
Regression suite
CI
Test case management system
Sanity suite
Manually triggered
Branch merge
Cypress dashboard
Slack channel
Regression Test example - Manual steps
Regression suite
Regression Test example - The code
describe('Alerts', function () {
before(function () {
cy.getUserAndLogin();
cy.launchGuidesList('iframes-page.html');
cy.intercept('GET', '**/route/to/layouts').as('loadLayouts');
cy.intercept('GET', '**/route/to/themes').as('loadThemes');
cy.createGuide({ layoutName: defaultLayoutNames.lightbox, isDefault: true });
});
after(function () {
cy.returnUser();
});
describe('Activation Settings Alerts', function () {
describe('Element found in multiple frames', function () {
it('C490 Selects an element, div, that exists in multiple frames and outlines them in red', function () {
// Adds a second step
ActionBar.actionBarContainer()
.find('.action-bar-container-header')
.should('be.visible');
ActionBar.stepsTrayToggle().click();
actionBarIframe()
.find('.action-bar-container')
.should('have.class', 'expanded');
ActionBar.newStepButton().click();
cy.wait('@loadThemes')
.its('response.statusCode')
.should('eq', 200);
cy.wait('@loadLayouts')
.its('response.statusCode')
.should('eq', 200);
LayoutChooser.getLayoutByName(defaultLayoutNames.lightbox, true).click();
actionBarIframe()
.find('.action-bar-container-tray-inner')
.find('.pendo-draggable[class*="has-draggable-"]')
.children()
.should('have.length', 2);
// Select target
CommonUFO.locationTab().should('be.visible').click();
EditContainerLocation.elementLocationChooser()
.find('.pendo-button')
.click();
LiveApplication.waitForNavigationControls();
LiveApplication.customTargetedElement('.title').click({ force: true });
EditContainerLocation.selectedElementLocation()
.should('contain', '.title');
// Change target type to custom css and input div
EditContainerLocation.elementLocationRadioButton('customCss').click();
EditContainerLocation.customCssInput()
.clear()
.type('div');
// Assert red outline on all divs targeted
iFrameTown.iFrameApplication()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame1()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame2()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame3()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame4()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
// Change target type to parent
EditContainerLocation.elementLocationRadioButton('suggestedMatch').click();
cy.get('div[style*="outline: red solid 2px;"]').should('have.length', 1);
// Assert prior div selection will not have red outlines
ActionBar.editStepButton().click();
cy.get('div[style*="outline: red solid 2px;"]').should('have.length', 0);
ActionBar.editStep(1).click();
cy.get('div[style*="outline: red solid 2px;"]').should('have.length', 1);
// Change target type to custom css and input div
EditContainerLocation.elementLocationRadioButton('customCss').click();
EditContainerLocation.customCssInput()
.clear()
.type('div');
// Assert red outline on all divs targeted
iFrameTown.iFrameApplication()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame1()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame2()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame3()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
iFrameTown.iFrame4()
.get('div[style*="outline: red solid 2px;"]')
.should('have.length', 2);
// Assert alert
Alerts.verifyAlertText('Step 2 uses an element target, but the target was found in multiple frames ' +
'in your application. This can potentially lead to inconsistent guide display');
Alerts.errorLink().click();
// Resolve alert
LiveApplication.waitForNavigationControls();
LiveApplication.customTargetedElement('.iframe-container').click({ force: true });
EditContainerLocation.selectedElementLocation()
.should('contain', 'iframe');
ActionBar.alertButton().click();
Alerts.verifyNoAlertText('You have no alerts.');
});
});
});
});
// Separate file for the Action Bar
newStepButton () {
return actionBarIframe().find('[data-cy="guide-step-add"]');
}
Regression suite
Regression Test example - Cypress test
Regression suite
Scheduled run
Regression suite
CI
Test case management system
Sanity suite
Manually triggered
Branch merge
Cypress dashboard
Slack channel
Test Retries & Cypress Dashboard
Cypress dashboard
Test Retries & Cypress Dashboard
Step 1: Enable test retries
Step 2: Check Flaky tests in Cypress Dashboard
Step 3: ????
Step 4: Profit
Cypress dashboard
Step 1: Enable test retries (it's really easy!)
Test retries is a feature where Cypress will automatically retry a failed test prior to marking it as failed.
Ensure you are on version >=5.0 and update your cypress.json (or config file):
Or visit the docs for other approaches
"retries": {
"runMode": 3,
"openMode": 0
}
Cypress dashboard
Step 2: Check Flaky tests in Cypress Dashboard
Cypress dashboard
Step 3: ????
Cypress dashboard
Step 4: Profit
Before
After
1. Flaky test fails
2. Engineer looks into failure as a priority
2. Cypress retries the test (the number of times specified) and the test passes
3. Upon investigation engineer notices a (potentially unrelated) test has failed
4. Engineer either fixes the test or reruns the test to see if it passes the second time
1. Flaky test fails
3. The flaky failure is recorded in the test results of Cypress Dashboard
4. The team work through any flaky tests recorded in Cypress Dashboard
Cypress dashboard
So how long does it take to run these tests?..
Sanity
Cypress dashboard
So how long does it take to run these tests?..
Regression
Cypress dashboard
Scheduled run
Regression suite
CI
Test case management system
Sanity suite
Manually triggered
Branch merge
Cypress dashboard
Slack channel
Slack channel reporting
Slack channel
Scheduled run
Regression suite
CI
Test case management system
Sanity suite
Manually triggered
Branch merge
Cypress dashboard
Slack channel
Test case management integration
Test case management system
Ask Questions at Sli.do
event code #cy-pendo
We now have...
We now have...
@bahmutov
Ask Questions at Sli.do event code
@georgepalf
By Cypress.io
In this webcast, we'll introduce one of Pendo’s unique products—Guides— and the team’s approach to testing this complex application.
When testing is easy, developers build better things faster and with confidence.