Svelte.js is a very interesting "disappearing" framework for writing web applications. Recently, the framework's crew came out with a simple centralized data store to be used with Svelte apps. The initial "Hello World" example application had a bug 🙃 immediately fixed by a pull request. But this immediately showed me an opportunity to write a few end to end tests to prevent any future problems. Of course I picked Cypress.io (full disclosure, I am VP of Engineering at Cypress) - an open source MIT-licensed test runner.
Before (and if) my pull request with E2E tests is merged into the main repo sveltejs/template-store, you can find the source and tests in bahmutov/template-store repository.
To run the web application we need to execute npm run dev
- this runs a static web server and Rollup bundler in watch mode. By default the app runs at http://localhost:5000
. I have installed Cypress with npm i -D cypress
(or just with yarn add cypress
) and opened it once with $(npm bin)/cypress open
. This scaffolded an empty settings file cypress.json
in the project root. I have added the following two options there to avoid hard coding the test url. Also, because I do not plan to use Cypress SaaS dashboard I have disabled recoding video during E2E test runs.
1 | { |
The simplest test case is to load the page and make sure the default greetings are displayed. I wrote file cypress/integration/spec.js with the following two tests.
1 | describe('Template store app', () => { |
The tests confirm the application loads and renders the expected initial text.
The data store reacts to the changed data, and the application should update the DOM if the store's data changes. Let us test it. First, we need to get the store reference. Because the website we are testing runs inside an iframe, we need to get the window reference. This will get us the window.app
variable. The store is attached to the app
object. A small utility function helps us avoid any boilerplate.
1 | const getStore = () => cy.window().its('app.store') |
In this implementation, the store uses localStorage
to persist the data, see main.js and useLocalStorage.js:
1 | // useLocalStorage.js |
Let us test that updating the store really updates the item in the localStorage
. This web application places its data under key my-app
, which we can grab from our E2E tests.
1 | it('uses localStorage as backup', () => { |
Great, but how do we test the initial data load? In Cypress runner each test run starts from nothing - the localStorage
is blown away between each unit test. How do we set the localStorage
to test that the store loads correctly? By using cy.visit()
options we can control the window
state before loading the website. I will place this test outside the describe('Template store app', ...)
block because we want a different site visit behavior.
1 | it('reads store from localStorage on load', () => { |
Great, our application is loading correctly. From now on we can be safe refactoring and adding new features - as long as the E2E tests are passing.