SWC-6477: End-to-end testing for SWC
Executive Summary
What technologies (Playwright, Cypress, Selenium, etc.) should we use to orchestrate tests?
Recommend using Playwright as end-to-end testing framework, because it
Utilizes Chrome DevTools Protocol (CDP) for direct control of the browser via websockets, which reduces test flakiness, increases test speed, and allows enhanced control of the browser with associated new features, as compared to tools implementing the WebDriver Protocol, which require an intermediary browser-driver.
Has cross-browser compatibility (Chrome, Firefox, Safari, Edge).
Has increasing popularity and community support and is backed by a large company (Microsoft).
Includes numerous feature differentiators that sets it apart from competitors, including out-of-the-box test parallelization locally and in CI, support for multiple users, multiple tabs, multiple browsers, and multiple origins, ability to write tests in multiple languages (TypeScript, Java, Python, .NET), superior developer tools, and locator and promise handling strategies that most closely align with existing WebEng Team products.
Associated trade-offs:
Not supported in much older browser versions and IE11.
Newer framework, with growing, but smaller community than other frameworks.
When should the end-to-end suite run? (e.g. per code change, cron schedule, before release)
Against what backend instance should the end-to-end suite run?
Recommend running end-to-end suite against backend dev stack locally during development and per code change in CI, so there is continual feedback about the impact of changes on functionality. Tests will need to clean-up any side-effects (e.g. creating a new project), so that tests can continue to pass against the same stack.
Consider creating a set of smoke tests that run against staging stack before release to exercise functionality that isn’t implemented on the dev stack (e.g. sending emails for account verification) and to verify key workflows against a copy of production data.
Test parallelization and sharding will hopefully allow the test suite to scale without increasingly slow run times, locally or in CI.
Can this work be generalized to also run against Portals?
If we wanted to use the same framework, certainly. If we wanted to re-use the same tests, potentially. SRC components are used in both SWC and Portals, so as long as flows are similar (or could be conditionally adjusted based on the current environment), the same tests could be run against both apps. There are configuration options (e.g. baseURL) that would support selecting the tested application at runtime, see here.
However, if the user flows are sufficiently different, then consider writing separate end-to-end tests or integration tests per application instead.
What scenarios should be tested?
Recommend testing the most critical features and important user workflows as well as features that are difficult to test in other formats, such as validating that data is persisted and displayed across multiple screens.
Recommend brainstorming as a team (and consider gathering input from other stakeholders, such as Governance, PMs, and Design) to create and prioritize a comprehensive list of critical features.
An initial list of important user workflows based on the Getting Started docs:
Log in (email, OAuth2 provider)
Create an account
Agree to code of conduct / terms of use
Request access to an entity
Create a project
Upload data, download data
Create a table, add data to a table, query a table
Other critical features to consider:
ACT / Governance, e.g. user cannot download file without meeting ACLs and ARs
Access workflows: e.g. a regular user requests access, an ACT user grants access, then the regular user has access
Action Items
Create ticket to introduce proof-of-concept to SWC – SWC-6514
Run against backend dev stack
Configure GitHub Actions with environment variables
Design test workflow so that can run tests with side effects in parallel locally (e.g. each dev has their own credentials) and potentially run CI (e.g. register new user for each run)
Publish doc to Confluence
Framework Selection
General Approach
I started by identifying a variety of browser automation tools (Cypress, Playwright, Puppeteer, Selenium WebDriver, TestCafe), and then narrowed down the list by evaluating their underlying protocols, cross-browser compatibility, relative popularity, and differentiating features. Once I had narrowed down to two frameworks, I set up a proof of concept with each to evaluate developer tools and to create a variety of small tests.
Background
End-to-end testing aims to simulate real user scenarios by testing the entire application flow. Browser automation tools are often used to automate the execution of these tests. Headless browsers, i.e. browsers that can run without displaying the UI, are useful for running these tests in CI. In the past, headless browsers weren’t native to the browsers that people actually used, but were developed separately (e.g. PhantomJS, based on WebKit). Browser automation tools used the WebDriver protocol, which uses a browser-driver to translate test script commands into commands the browser could execute.
However, since 2017, Chrome and Firefox have added native support for headless browsers, so automated tests can be run in the officially supported browsers. In addition, the Chrome DevTools Protocol was released, which allows direct communication between the test script and the browser via web sockets. New browser automation tools were released that took advantage of this protocol or the paradigm of direct communication with the browser.
A next generation W3C WebDriver protocol called WebDriver BiDi aims to standardize browser automation protocols and combine the best of both WebDriver “Classic” and CDP, but is currently under development.
I will start by evaluating the pros/cons of the protocols underlying the browser automation tools.
1) Underlying Protocols: Intermediary vs Direct Communication
| WebDriver Protocol | Chrome DevTools Protocol (CDP) | Native Scripting | WebDriver Bidi (BiDirectional) |
Description | Allows web browser automation using a browser-driver as an intermediary to translate the test script into commands that the browser can execute. Standardized by W3C. | Allows direct control of the browser via websockets. Maintained / standardized by the browser providers. | Runs the automation script “in-process” with the browser, so the browse is directly controlled by injected script | Next generation of W3C WebDriver protocol that aims to provide a stable API implemented by all browsers with bidirectional functionality via web sockets. In progress. |
Pros |
|
|
|
|
Cons |
|
|
|
|
Frameworks | Selenium WebDriver | Selenium WebDriver Devtools Service*, Playwright, Puppeteer, TestCafe | Cypress** | N/A |
*Selenium WebDriver offers a “Devtools Service”, which allows running CDP commands in tests. The service uses Puppeteer under the hood.
**Cypress currently uses its own implementation to control the browser in process, but per this comment, they are working on using CDP to communicate with the browser.
Summary
While the WebDriver protocol is a more established protocol with a large community, the lack of direct communication between the test script and browser execution leads to test flakiness. Additionally, there are certain features that can’t be readily implemented, such as manipulating network requests. While W3C is working to implement a next generation WebDriver protocol that uses web sockets for direct communication (WebDriver BiDi), the protocol is still in early stages and not fully implemented in any testing frameworks.
Both Chrome DevTools Protocol and Native Scripting approaches offer direct communication between the testing tool and browser, so the script can perform actionability checks before performing actions, such as waiting for network calls to finish or elements to appear before proceeding, which reduces test flakiness. New features, based on the enhanced control of the browser, can also be implemented.
Will proceed with tools that use protocols based on direct communication to decrease test flakiness and leverage features based on enhanced browser control: Cypress, Playwright, Puppeteer, Selenium WebDriver Devtools, TestCafe.
2) Cross-Browser Compatibility
| Cypress | Playwright | Puppeteer* | TestCafe |
Chrome | Yes | Yes | Yes | Yes |
Firefox | Yes | Yes | Experimental | Yes |
Safari | Experimental | Yes | No | Yes |
Edge | Yes | Yes | No | Yes |
*Selenium WebDriver Devtools Service uses Puppeteer under the hood.
Summary
Among the browser automation tools that directly communicate with the browser, either via CDP or via native scripting, Puppeteer has the least cross-browser compatibility without support for Safari or Edge.
Will proceed with tools that at least have experimental support for all major browsers: Cypress, Playwright, TestCafe.
3) Popularity / Community / Maintenance
Ideally, the selected testing framework will continue to be maintained and improved for many years into the future. Selecting an increasingly popular framework will also increase the likelihood that WebEng developers, both existing and new hires, are already familiar with the framework, which will decrease spin-up time and make it easier to maintain long term.
However, predicting which frameworks will make the cut is difficult. Here, popularity, a large community, and active maintenance of the framework are used as indirect measures of the framework’s potential longevity.
TestCafe is the oldest framework –
TestCafe: initially released Nov 7, 2016; 6.7 years old
Cypress: initially released Sep 10, 2017; 5.8 years old
Playwright: initially released Jan 31, 2020; 3.4 years old
However, Cypress has largest community, based on tags on stackoverflow (July 20, 2023):
[cypress]: 9,680 questions
[playwright]: 2,234 questions
[testcafe]: 1,845 questions
And the most downloads (July 20, 2023):
But Playwright popularity seems to be rapidly increasing, based on GitHub repository star history (July 20, 2023):
And more active management of their GitHub open issues (July 20, 2023):
Cypress: 1,336 open issues, 11,697 closed issues
Playwright: 616 open issues, 9,883 closed issues
TestCafe: 132 open issues, 4,409 closed issues
Summary
TestCafe is the oldest framework, but appears to be the least popular. Cypress is the most popular based on number of downloads and stackoverflow questions. However, Playwright appears to be increasing quickly in popularity since its release and has more active management of open issues.
Will proceed with the most popular or increasingly popular tools: Cypress, Playwright.
4) Cypress vs Playwright
Basics
| Cypress | Playwright |
Repo | ||
Company Backer | Cypress | Microsoft |
First release / Age | Sep 10, 2017, 5.8 years old
| Jan 31, 2020, 3.4 years old |
Size / Dependencies | 5MB, 42 dependencies (v12.17.2)
If we want to use Cypress Testing Library, then add: 42.8kB, 2 dependencies (v9.0.0) | 24.2kB, 1 dependency (v1.36.1) |
License | MIT license https://docs.cypress.io/faq/questions/general-questions-faq#Is-Cypress-free-and-open-source | Apache 2.0 |
Cost | Free, unless we want to use Cypress Cloud, which has pricing tiers (starting from free) - https://www.cypress.io/pricing/ | Free |
Supported Languages | Javascript only. Can support Typescript with configuration. Will not be able to support other languages due to its “in process” implementation.
https://docs.cypress.io/guides/references/trade-offs#Inside-the-browser
| Typescript, Python, Java, .NET
https://playwright.dev/docs/languages
|
Supported Operating Systems | Windows, MacOS, Linux
https://docs.cypress.io/guides/getting-started/installing-cypress#System-requirements | Windows, MacOS, Ubuntu
|
Cross-browser Compatibility | Chrome Firefox Safari (experimental) Edge | Chrome Firefox Safari Edge |
Used elsewhere in Web Engineering products | Yes, in Agora. However, implementation is currently minimal (one test) and doesn’t support the Cypress GUI. | No |
Features
| Cypress | Playwright |
Auto-wait and retry | Yes
| Yes
|
Component testing | Yes
| Experimental
|
Device size | Yes, can control viewport size, but generally requires plugins for more control over browser settings and permissions.
https://docs.cypress.io/api/commands/viewport
| Yes, emulates viewport size, devices, browser settings (e.g. dark mode) and permissions, language/location/timezone out of the box.
|
Hover event support | No, but offers workarounds
| Yes
|
iFrame support | Limited, but planned to improve in the future.
| Yes
|
Mock network requests | Yes
| Yes
|
Multiple browser tabs | No, and cannot be supported in the future due to “in process” design.
https://docs.cypress.io/guides/references/trade-offs#Multiple-tabs | Yes
|
Multiple browsers | No, and cannot be supported in the future due to “in process” design.
https://docs.cypress.io/guides/references/trade-offs#Multiple-browsers-open-at-the-same-time | Yes
|
Multiple users | No, and cannot be supported in the future due to “in process” design.
https://docs.cypress.io/guides/references/trade-offs#Multiple-browsers-open-at-the-same-time | Yes
https://playwright.dev/docs/browser-contexts#multiple-contexts-in-a-single-test
|
Reuse authentication state | Yes
https://docs.cypress.io/api/cypress-api/custom-commands#Log-in-command-using-UI https://www.cypress.io/blog/2021/08/04/authenticate-faster-in-tests-cy-session-command/ | Yes
https://playwright.dev/docs/auth#basic-shared-account-in-all-tests |
Parallelization of tests (CI) | Yes, per file, but requires Cypress Cloud (which starts at free tier, but only for 3 users and limited test results)
https://www.cypress.io/pricing https://docs.cypress.io/guides/cloud/smart-orchestration/parallelization | Yes, out of the box, per file or can be configured per test in file
|
Parallelization of tests (locally) | Not supported / not recommended (would require too many resources), but could be done manually
https://docs.cypress.io/guides/cloud/smart-orchestration/parallelization https://stackoverflow.com/a/62501194 | Yes, out of the box, per file or can be configured per test in file
|
Test sharding | Yes, but (I think) that's their parallelization strategy -- split tests up and run on different machines, rather than running tests in parallel on the same machine
https://docs.cypress.io/guides/cloud/smart-orchestration/parallelization#Overview | Yes, with configuration options for GitHub Actions workflows
https://playwright.dev/docs/test-parallel#shard-tests-between-multiple-machines
|
Promise handling | “Promise-like” method chaining
https://mtlynch.io/notes/cypress-vs-playwright/#playwright-requires-less-domain-specific-knowledge https://www.qawolf.com/blog/why-qa-wolf-chose-playwright-over-cypress | Standard promises
https://mtlynch.io/notes/cypress-vs-playwright/#playwright-requires-less-domain-specific-knowledge https://www.qawolf.com/blog/why-qa-wolf-chose-playwright-over-cypress |
Tab key support | No
| Yes
https://playwright.dev/docs/api/class-keyboard#keyboard-down |
Test Isolation | Configurable
| Yes, via browser contexts
|
Developer Tools
| Cypress | Playwright |
IDE Integration |
|
|
Test generation |
|
|
Debugging |
|
|