Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit d9b7e07

Browse files
authored
Add visual tests using Percy in Cypress (#8610)
* Add basic Percy tests * Run Percy in CI * Fix snapshot timing * Fix bad selector * Hide another bit of dynamic text * Add docs
1 parent c122c5c commit d9b7e07

File tree

10 files changed

+218
-9
lines changed

10 files changed

+218
-9
lines changed

.github/workflows/element-build-and-test.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,20 @@ jobs:
6767
- name: Run Cypress tests
6868
uses: cypress-io/github-action@v2
6969
with:
70-
# The built in Electron runner seems to grind to a halt trying
70+
# The built-in Electron runner seems to grind to a halt trying
7171
# to run the tests, so use chrome.
7272
browser: chrome
7373
start: npx serve -p 8080 webapp
7474
record: true
75+
command-prefix: 'yarn percy exec --'
7576
env:
7677
# pass the Dashboard record key as an environment variable
7778
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
79+
# pass the Percy token as an environment variable
80+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
81+
# Use existing chromium rather than downloading another
82+
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true
83+
PERCY_BROWSER_EXECUTABLE: /usr/bin/chromium-browser
7884
# pass GitHub token to allow accurately detecting a build vs a re-run build
7985
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8086

.percy.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
version: 2
2+
snapshot:
3+
widths:
4+
- 1024
5+
- 1920

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
![Tests](https://github.com/matrix-org/matrix-react-sdk/actions/workflows/tests.yml/badge.svg)
33
![Static Analysis](https://github.com/matrix-org/matrix-react-sdk/actions/workflows/static_analysis.yaml/badge.svg)
44
[![matrix-react-sdk](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/ppvnzg/develop&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/ppvnzg/runs)
5+
[![This project is using Percy.io for visual regression testing.](https://percy.io/static/images/percy-badge.svg)](https://percy.io/dfde73bd/matrix-react-sdk)
56
[![Weblate](https://translate.element.io/widgets/element-web/-/matrix-react-sdk/svg-badge.svg)](https://translate.element.io/engage/element-web/)
67
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=matrix-react-sdk&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=matrix-react-sdk)
78
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=matrix-react-sdk&metric=coverage)](https://sonarcloud.io/summary/new_code?id=matrix-react-sdk)

cypress/integration/1-register/register.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,37 @@ describe("Registration", () => {
3434

3535
it("registers an account and lands on the home screen", () => {
3636
cy.get(".mx_ServerPicker_change", { timeout: 15000 }).click();
37+
cy.get(".mx_ServerPickerDialog_continue").should("be.visible");
38+
cy.percySnapshot("Server Picker");
39+
3740
cy.get(".mx_ServerPickerDialog_otherHomeserver").type(synapse.baseUrl);
3841
cy.get(".mx_ServerPickerDialog_continue").click();
3942
// wait for the dialog to go away
4043
cy.get('.mx_ServerPickerDialog').should('not.exist');
4144

45+
cy.get("#mx_RegistrationForm_username").should("be.visible");
46+
// Hide the server text as it contains the randomly allocated Synapse port
47+
const percyCSS = ".mx_ServerPicker_server { visibility: hidden !important; }";
48+
cy.percySnapshot("Registration", { percyCSS });
49+
4250
cy.get("#mx_RegistrationForm_username").type("alice");
4351
cy.get("#mx_RegistrationForm_password").type("totally a great password");
4452
cy.get("#mx_RegistrationForm_passwordConfirm").type("totally a great password");
4553
cy.startMeasuring("create-account");
4654
cy.get(".mx_Login_submit").click();
4755

56+
cy.get(".mx_RegistrationEmailPromptDialog").should("be.visible");
57+
cy.percySnapshot("Registration email prompt", { percyCSS });
4858
cy.get(".mx_RegistrationEmailPromptDialog button.mx_Dialog_primary").click();
59+
4960
cy.stopMeasuring("create-account");
61+
cy.get(".mx_InteractiveAuthEntryComponents_termsPolicy").should("be.visible");
62+
cy.percySnapshot("Registration terms prompt", { percyCSS });
63+
5064
cy.get(".mx_InteractiveAuthEntryComponents_termsPolicy input").click();
5165
cy.startMeasuring("from-submit-to-home");
5266
cy.get(".mx_InteractiveAuthEntryComponents_termsSubmit").click();
67+
5368
cy.url().should('contain', '/#/home');
5469
cy.stopMeasuring("from-submit-to-home");
5570
});

cypress/integration/2-login/login.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ describe("Login", () => {
4141
});
4242

4343
it("logs in with an existing account and lands on the home screen", () => {
44-
cy.get(".mx_ServerPicker_change", { timeout: 15000 }).click();
44+
cy.get("#mx_LoginForm_username", { timeout: 15000 }).should("be.visible");
45+
cy.percySnapshot("Login");
46+
47+
cy.get(".mx_ServerPicker_change").click();
4548
cy.get(".mx_ServerPickerDialog_otherHomeserver").type(synapse.baseUrl);
4649
cy.get(".mx_ServerPickerDialog_continue").click();
4750
// wait for the dialog to go away

cypress/support/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ limitations under the License.
1616

1717
/// <reference types="cypress" />
1818

19+
import "@percy/cypress";
20+
1921
import "./performance";
2022
import "./synapse";
2123
import "./login";

cypress/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"target": "es2016",
44
"lib": ["es2020", "dom"],
5-
"types": ["cypress"],
5+
"types": ["cypress", "@percy/cypress"],
66
"moduleResolution": "node"
77
},
88
"include": ["**/*.ts"]

docs/cypress.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ It aims to cover:
66
* How to run the tests yourself
77
* How the tests work
88
* How to write great Cypress tests
9+
* Visual testing
910

1011
## Running the Tests
1112
Our Cypress tests run automatically as part of our CI along with our other tests,
@@ -166,3 +167,14 @@ already familiar with Cypress.
166167

167168
This is a small selection - the Cypress best practices guide, linked above, has more good advice, and we
168169
should generally try to adhere to them.
170+
171+
## Percy Visual Testing
172+
We also support visual testing via Percy, this extracts the DOM from Cypress and renders it using custom renderers
173+
for Safari, Firefox, Chrome & Edge, allowing us to spot visual regressions before they become release regressions.
174+
Right now we run it as part of the standard Pull Request CI automation but due to only having 25k screenshots/month,
175+
and each `cy.percySnapshot()` call results in 8 screenshots (4 browsers, 2 sizes) this could quickly be exhausted and
176+
at that point we would likely run it on a CRON interval or before releases.
177+
178+
To record a snapshot use `cy.percySnapshot()`, you may have to pass `percyCSS` into the 2nd argument to hide certain
179+
elements which contain dynamic/generated data to avoid them cause false positives in the Percy screenshot diffs.
180+

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@
133133
"@babel/traverse": "^7.12.12",
134134
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
135135
"@peculiar/webcrypto": "^1.1.4",
136+
"@percy/cli": "^1.1.4",
137+
"@percy/cypress": "^3.1.1",
136138
"@sentry/types": "^6.10.0",
137139
"@sinonjs/fake-timers": "^9.1.2",
138140
"@types/classnames": "^2.2.11",

0 commit comments

Comments
 (0)