Skip to content

Commit

Permalink
Template tests POC using @web/test-runner (sveltejs#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenkunz committed Jun 7, 2021
1 parent b1aa656 commit 1d99ee1
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 1 deletion.
Expand Up @@ -4,10 +4,13 @@
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
"preview": "svelte-kit preview"
"preview": "svelte-kit preview",
"test": "wtr \"src/**/*.test.js\""
},
"devDependencies": {
"@sveltejs/kit": "workspace:*",
"@web/test-runner": "^0.13.5",
"assert": "^2.0.0",
"svelte": "^3.34.0"
},
"type": "module",
Expand Down
16 changes: 16 additions & 0 deletions packages/create-svelte/templates/default/src/test/Counter.test.js
@@ -0,0 +1,16 @@
import { strict as assert } from 'assert';
import Counter from '$lib/Counter/index.svelte';

describe('Counter', () => {
it('should increment when plus button is clicked', async () => {
const target = document.getElementById('svelte');
new Counter({ target });
const plusButton = target.getElementsByTagName('button')[1];
const counter = target.querySelectorAll('.counter-digits strong')[1];
assert.equal(counter.innerText, '0');
plusButton.click();
// you probably want to use fake timers in your real tests!
await new Promise((resolve) => setTimeout(resolve, 500));
assert.equal(counter.innerText, '1');
});
});
10 changes: 10 additions & 0 deletions packages/create-svelte/templates/default/src/test/HomePage.test.js
@@ -0,0 +1,10 @@
import { strict as assert } from 'assert';
import HomePage from '../routes/index.svelte';

describe('HomePage', () => {
it('should render', () => {
const target = document.getElementById('svelte');
new HomePage({ target });
assert(/try editing src\/routes\/index.svelte/.test(target.innerText));
});
});
79 changes: 79 additions & 0 deletions packages/create-svelte/templates/default/web-test-runner.config.js
@@ -0,0 +1,79 @@
import { spawn } from 'child_process';

/*
* Implementing plugin inline as a POC. This would be extracted to a separate
* npm module following a pattern similar to @snowpack/web-test-runner-plugin:
* https://github.com/snowpackjs/snowpack/tree/main/plugins/web-test-runner-plugin
* or vite-web-test-runner-plugin:
* https://github.com/betaboon/vite-web-test-runner-plugin
*/
const svelteKitPlugin = function () {
let server;

// quick hack; use more resilient approach in real plugin
function randomPort(min = 49152, max = 65535) {
return Math.floor(Math.random() * (max - min) + min);
}

// Currently, svelte-kit does not expose a method to the outside world to
// start a dev server in JS-land. Work-around for POC: spawn a child process
// that shells-out to svelte-kit cli. For real plugin, extract and export a
// method from svelte-kit to start a dev server.
function startTestServer(port) {
const testServer = spawn('npx', ['svelte-kit', 'dev', `--port=${port}`]);

testServer.stderr.on('data', (data) => {
console.error(data.toString());
});

testServer.stdout.on('data', (data) => {
console.log(data.toString());
});

return new Promise((resolve, reject) => {
testServer.stdout.on('data', (data) => {
if (/http:\/\/localhost:\d+/.test(data)) {
resolve(testServer);
}
});

testServer.on('close', reject);
});
}

return {
name: 'svelte-kit-plugin',

async serverStart({ app }) {
const port = randomPort();
server = await startTestServer(port);
app.use((ctx, next) => {
ctx.redirect(`http://localhost:${port}${ctx.originalUrl}`);
});
},

async serverStop() {
return server.kill();
}
};
};

process.env.NODE_ENV = 'test';

export default {
plugins: [svelteKitPlugin()],
testRunnerHtml: (testFramework) => `
<html>
<head>
<script>
global = window;
process = { env: { NODE_ENV: "test" } };
</script>
<script type="module" src="${testFramework}"></script>
</head>
<body>
<div id="svelte"></div>
</body>
</html>
`
};

0 comments on commit 1d99ee1

Please sign in to comment.