Skip to content

Commit

Permalink
ci: add tests (#48)
Browse files Browse the repository at this point in the history
* ci: add tests

* chore: remove vitest imports
docs: update contributing guide

* chore: update node adapter test message

* chore: update contributing guide

* chore: use `existsSync` and `readFileSync` in test

* chore: rollback changes in package.json files + fix lint

* chore: add `preview-node` script to example

* chore: update pnpm to 8.4.0

* ci: add client tests (#50)

* ci: add client tests

* chore: use `Promise.race` when awaiting sw registration

* docs: add installing Playwright Chromium browser hint before running tests

* chore: update to pnpm 8.5.0

* chore: update browser test description

* chore: remove Vitest globals (IntelliJ complains)

* chrore: update vitest and lock file
  • Loading branch information
userquin committed May 19, 2023
1 parent 921856e commit 945214a
Show file tree
Hide file tree
Showing 13 changed files with 561 additions and 45 deletions.
15 changes: 1 addition & 14 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
{
"extends": ["@antfu"],
"overrides": [
{
"files": [
"**/*.md/*.*"
],
"rules": {
"@typescript-eslint/no-this-alias": "off",
"n/handle-callback-err": "off",
"no-restricted-syntax": "off",
"no-labels": "off"
}
}
]
"extends": ["@antfu"]
}
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ dist
dev-dist
# intellij stuff
.idea/
# routify
.routify/
/test-results/
/playwright-report/
/playwright/.cache/
18 changes: 8 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Hi! We are really excited that you are interested in contributing to `@vite-pwa/sveltekit`. Before submitting your contribution, please make sure to take a moment and read through the following guide.

Refer also to https://github.com/antfu/contribute.

## Set up your local development environment

The `@vite-pwa/sveltekit` repo is a monorepo using pnpm workspaces. The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/).
Expand All @@ -13,7 +14,7 @@ To develop and test the `@vite-pwa/sveltekit` package:

2. Ensure using the latest Node.js (16.14+)

3. `@vite-pwa/sveltekit` uses pnpm v7. If you are working on multiple projects with different versions of pnpm, it's recommend to enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`.
3. `@vite-pwa/sveltekit` uses pnpm v8. If you are working on multiple projects with different versions of pnpm, it's recommend to enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`.

4. Check out a branch where you can work and commit your changes:
```shell
Expand All @@ -26,15 +27,12 @@ git checkout -b my-new-branch

## Testing changes

The `vite-plugin-pwa` repo includes a set of examples where you can test the changes (you can find them on examples folder), you should check your changes against each framework using the `cli` for running examples:
- `pnpm run examples`: select `vue` framework and default options on the cli (you can also test another options)
- `pnpm run examples`: select `react` framework and default options on the cli (you can also test another options)
- `pnpm run examples`: select `preact` framework and default options on the cli (you can also test another options)
- `pnpm run examples`: select `svelte` framework and default options on the cli (you can also test another options)
- `pnpm run examples`: select `sveltekit` framework and default options on the cli (you can also test another options)
- `pnpm run examples`: select `solid` framework and default options on the cli (you can also test another options)
To test your changes locally, change to `examples/sveltekit-ts` folder and run `pnpm run build-<example> && pnpm run preview` where `<example>` is the name of the example you want to test.

## Running tests

Before running tests, you'll need to install [Playwright](https://playwright.dev/) Chromium browser: `pnpm playwright install chromium`.

> The default options from the `cli` are just to check your changes are not breaking major ui/app frameworks build: `generateSW` strategy, `Prompt for update` behavior and `Enable periodic SW updates` to `no`.
Run `pnpm run test` in `@vite-pwa/sveltekit`'s root folder or inside `examples/sveltekit-ts` folder after build `@vite-pwa/sveltekit`.

> If your changes are specific to some behavior, just use the corresponding option on the `cli`.

6 changes: 6 additions & 0 deletions examples/sveltekit-ts/adapter.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AdapterNode from '@sveltejs/adapter-node';
import AdpaterStatic from '@sveltejs/adapter-static';

export const nodeAdapter = process.env.NODE_ADAPTER === 'true'

export const adapter = nodeAdapter ? AdapterNode() : AdpaterStatic()
44 changes: 44 additions & 0 deletions examples/sveltekit-ts/client-test/sw.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {test, expect} from '@playwright/test';
import {generateSW} from "../pwa.mjs";

test('The service worker is registered and cache storage is present', async ({ page}) => {
await page.goto('/');

const swURL = await page.evaluate(async () => {
const registration = await Promise.race([
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.serviceWorker.ready,
new Promise((_, reject) => setTimeout(() => reject(new Error('Service worker registration failed: time out')), 10000))
])
return registration.active?.scriptURL
});
const swName = generateSW ? 'sw.js' : 'prompt-sw.js'
expect(swURL).toBe(`http://localhost:4173/${swName}`);

const cacheContents = await page.evaluate(async () => {
const cacheState: Record<string, Array<string>> = {};
for (const cacheName of await caches.keys()) {
const cache = await caches.open(cacheName);
cacheState[cacheName] = (await cache.keys()).map((req) => req.url);
}
return cacheState;
});

expect(Object.keys(cacheContents).length).toEqual(1)

const key = 'workbox-precache-v2-http://localhost:4173/'

expect(Object.keys(cacheContents)[0]).toEqual(key)

const urls = cacheContents[key].map(url => url.slice('http://localhost:4173/'.length))

/*
'http://localhost:4173/about?__WB_REVISION__=38251751d310c9b683a1426c22c135a2',
'http://localhost:4173/?__WB_REVISION__=073370aa3804305a787b01180cd6b8aa',
'http://localhost:4173/manifest.webmanifest?__WB_REVISION__=27df2fa4f35d014b42361148a2207da3'
*/
expect(urls.some(url => url.startsWith('manifest.webmanifest?__WB_REVISION__='))).toEqual(true)
expect(urls.some(url => url.startsWith('?__WB_REVISION__='))).toEqual(true)
expect(urls.some(url => url.startsWith('about?__WB_REVISION__='))).toEqual(true)
});
20 changes: 16 additions & 4 deletions examples/sveltekit-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,27 @@
"scripts": {
"sw-dev": "vite dev",
"dev": "vite dev",
"build": "vite build",
"build-generate-sw": "GENERATE_SW=true vite build",
"build-generate-sw-node": "NODE_ADAPTER=true GENERATE_SW=true vite build",
"build-inject-manifest": "vite build",
"build-inject-manifest-node": "NODE_ADAPTER=true vite build",
"build-self-destroying": "SELF_DESTROYING_SW=true vite build",
"preview": "vite preview",
"preview": "vite preview --port=4173",
"preview-node": "PORT=4173 node build",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "eslint .",
"lint-fix": "nr lint --fix"
"lint-fix": "nr lint --fix",
"test-generate-sw": "nr build-generate-sw && GENERATE_SW=true vitest run && GENERATE_SW=true playwright test",
"test-generate-sw-node": "nr build-generate-sw-node && NODE_ADAPTER=true GENERATE_SW=true vitest run && NODE_ADAPTER=true GENERATE_SW=true playwright test",
"test-inject-manifest": "nr build-inject-manifest && vitest run && playwright test",
"test-inject-manifest-node": "nr build-inject-manifest-node && NODE_ADAPTER=true vitest run && NODE_ADAPTER=true playwright test",
"test": "nr test-generate-sw && nr test-generate-sw-node && nr test-inject-manifest && nr test-inject-manifest-node"
},
"devDependencies": {
"@playwright/test": "^1.33.0",
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/adapter-node": "^1.2.4",
"@sveltejs/kit": "^1.18.0",
"@types/cookie": "^0.5.1",
"@typescript-eslint/eslint-plugin": "^5.59.6",
Expand All @@ -25,7 +36,8 @@
"svelte-check": "^3.3.2",
"svelte-preprocess": "^5.0.3",
"tslib": "^2.5.2",
"typescript": "^5.0.4"
"typescript": "^5.0.4",
"vitest": "^0.31.1"
},
"type": "module",
"dependencies": {
Expand Down
93 changes: 93 additions & 0 deletions examples/sveltekit-ts/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { defineConfig, devices } from '@playwright/test'

const url = 'http://localhost:4173'

import { nodeAdapter } from './adapter.mjs'

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './client-test',
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
outputDir: 'test-results/',
timeout: 5 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 1000,
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'line',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: url,

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },

// {
// name: 'webkit',
// use: { ...devices['Desktop Safari'] },
// },

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ..devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
webServer: {
command: nodeAdapter ? 'pnpm run preview-node' : 'pnpm run preview',
url,
reuseExistingServer: !process.env.CI,
},
});
2 changes: 1 addition & 1 deletion examples/sveltekit-ts/pwa.mjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const generateSW = true;
export const generateSW = process.env.GENERATE_SW === 'true'
6 changes: 3 additions & 3 deletions examples/sveltekit-ts/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import adapter from '@sveltejs/adapter-static';
import preprocess from 'svelte-preprocess';
// you don't need to do this if you're using generateSW strategy in your app
import { generateSW } from './pwa.mjs';
import { generateSW } from './pwa.mjs'
import { adapter } from './adapter.mjs'

/** @type {import('@sveltejs/kit').Config} */
const config = {
Expand All @@ -10,7 +10,7 @@ const config = {
preprocess: preprocess(),

kit: {
adapter: adapter(),
adapter,
serviceWorker: {
register: false,
},
Expand Down
31 changes: 31 additions & 0 deletions examples/sveltekit-ts/test/build.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, it } from 'vitest'
import { existsSync, readFileSync } from 'node:fs'
import { generateSW } from '../pwa.mjs'
import { nodeAdapter } from '../adapter.mjs'

describe(`test-build: ${nodeAdapter ? 'node' : 'static'} adapter`, () => {
it(`service worker is generated: ${generateSW ? 'sw.js' : 'prompt-sw.js'}`, () => {
const swName = `./build/${nodeAdapter ? 'client/': ''}${generateSW ? 'sw.js' : 'prompt-sw.js'}`
expect(existsSync(swName), `${swName} doesn't exist`).toBeTruthy()
const webManifest = `./build/${nodeAdapter ? 'client/': ''}manifest.webmanifest`
expect(existsSync(webManifest), `${webManifest} doesn't exist`).toBeTruthy()
const swContent = readFileSync(swName, 'utf-8')
let match: RegExpMatchArray | null
if (generateSW) {
match = swContent.match(/define\(\['\.\/(workbox-\w+)'/)
expect(match && match.length === 2, `workbox-***.js entry not found in ${swName}`).toBeTruthy()
const workboxName = `./build/${nodeAdapter ? 'client/': ''}${match?.[1]}.js`
expect(existsSync(workboxName),`${workboxName} doesn't exist`).toBeTruthy()
}
match = swContent.match(/"url":\s*"manifest\.webmanifest"/)
expect(match && match.length === 1, 'missing manifest.webmanifest in sw precache manifest').toBeTruthy()
match = swContent.match(/"url":\s*"\/"/)
expect(match && match.length === 1, 'missing entry point route (/) in sw precache manifest').toBeTruthy()
match = swContent.match(/"url":\s*"about"/)
expect(match && match.length === 1,'missing about route (/about) in sw precache manifest').toBeTruthy()
if (nodeAdapter) {
match = swContent.match(/"url":\s*"server\//)
expect(match === null, 'found server/ entries in sw precache manifest').toBeTruthy()
}
})
})
7 changes: 7 additions & 0 deletions examples/sveltekit-ts/vitest.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
include: ['test/*.test.ts']
}
})
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"lint": "eslint .",
"lint-fix": "nr lint --fix",
"prepublishOnly": "npm run build",
"release": "bumpp && npm publish"
"release": "bumpp && npm publish",
"test": "pnpm run -C examples/sveltekit-ts test"
},
"peerDependencies": {
"@sveltejs/kit": "^1.3.1",
Expand Down
Loading

0 comments on commit 945214a

Please sign in to comment.