mirror of
https://github.com/morris/vanilla-todo.git
synced 2025-01-17 04:38:14 +01:00
add basic testing, fix #8
This commit is contained in:
parent
97c1b625a3
commit
9d1c3b7b8f
23
README.md
23
README.md
@ -532,7 +532,25 @@ Reference:
|
|||||||
|
|
||||||
## 4. Testing
|
## 4. Testing
|
||||||
|
|
||||||
_TODO_
|
I've implemented one end-to-end test and one unit test
|
||||||
|
using [Playwright](https://playwright.dev/).
|
||||||
|
This was straightforward besides small details like the `*.mjs` extension
|
||||||
|
and the fact that you cannot use named imports when importing from
|
||||||
|
`public/scripts`.
|
||||||
|
|
||||||
|
There's a lot more to explore here, but it's not much different from
|
||||||
|
testing other frontend stacks. It's actually simpler as there was zero
|
||||||
|
configuration and just one dependency.
|
||||||
|
|
||||||
|
However, it's currently lacking code coverage. Playwright provides some
|
||||||
|
[code coverage facilities](https://playwright.dev/docs/api/class-coverage)
|
||||||
|
but it's not straight-forward to produce a standard LCOV report from that,
|
||||||
|
and it would probably be difficult to unify end-to-end and unit test coverage.
|
||||||
|
|
||||||
|
Reference:
|
||||||
|
|
||||||
|
- [addItem.test.mjs](./test/e2e/addItem.test.mjs)
|
||||||
|
- [util.test.mjs](./test/unit/util.test.mjs)
|
||||||
|
|
||||||
## 5. Assessment
|
## 5. Assessment
|
||||||
|
|
||||||
@ -615,6 +633,7 @@ and some opinionated statements based on my experience in the industry.
|
|||||||
- Little indirection
|
- Little indirection
|
||||||
- Low coupling
|
- Low coupling
|
||||||
- The result is literally just a bunch of HTML, CSS, and JS files.
|
- The result is literally just a bunch of HTML, CSS, and JS files.
|
||||||
|
- Straight-forward, zero-config testing with Playwright
|
||||||
|
|
||||||
All source files (HTML, CSS and JS) combine to **under 2400 lines of code**,
|
All source files (HTML, CSS and JS) combine to **under 2400 lines of code**,
|
||||||
including comments and empty lines.
|
including comments and empty lines.
|
||||||
@ -663,6 +682,7 @@ would reduce the comparably low code size (see above) even further.
|
|||||||
continuously monitor regressions with extensive test suites.
|
continuously monitor regressions with extensive test suites.
|
||||||
The cost of browser testing is surely a lot higher
|
The cost of browser testing is surely a lot higher
|
||||||
when using a vanilla approach.
|
when using a vanilla approach.
|
||||||
|
- No code coverage from tests
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -805,6 +825,7 @@ Thanks!
|
|||||||
|
|
||||||
### 05/2023
|
### 05/2023
|
||||||
|
|
||||||
|
- Add basic testing
|
||||||
- Fix stylelint errors
|
- Fix stylelint errors
|
||||||
- Update dependencies
|
- Update dependencies
|
||||||
|
|
||||||
|
82
package-lock.json
generated
82
package-lock.json
generated
@ -9,6 +9,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.33.0",
|
||||||
"eslint": "^8.20.0",
|
"eslint": "^8.20.0",
|
||||||
"eslint-plugin-compat": "^4.0.2",
|
"eslint-plugin-compat": "^4.0.2",
|
||||||
"http-server": "^14.1.1",
|
"http-server": "^14.1.1",
|
||||||
@ -316,6 +317,25 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@playwright/test": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-YunBa2mE7Hq4CfPkGzQRK916a4tuZoVx/EpLjeWlTVOnD4S2+fdaQZE0LJkbfhN5FTSKNLdcl7MoT5XB37bTkg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"playwright-core": "1.33.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"playwright": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tsconfig/node14": {
|
"node_modules/@tsconfig/node14": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
@ -328,6 +348,12 @@
|
|||||||
"integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
|
"integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
|
||||||
|
"integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/normalize-package-data": {
|
"node_modules/@types/normalize-package-data": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
|
||||||
@ -1154,6 +1180,20 @@
|
|||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@ -2121,6 +2161,18 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/playwright-core": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-aizyPE1Cj62vAECdph1iaMILpT0WUDCq3E6rW6I+dleSbBoGbktvJtzS6VHkZ4DKNEOG9qJpiom/ZxO+S15LAw==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"playwright": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/portfinder": {
|
"node_modules/portfinder": {
|
||||||
"version": "1.0.32",
|
"version": "1.0.32",
|
||||||
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
|
||||||
@ -3352,6 +3404,17 @@
|
|||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@playwright/test": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-YunBa2mE7Hq4CfPkGzQRK916a4tuZoVx/EpLjeWlTVOnD4S2+fdaQZE0LJkbfhN5FTSKNLdcl7MoT5XB37bTkg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"fsevents": "2.3.2",
|
||||||
|
"playwright-core": "1.33.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@tsconfig/node14": {
|
"@tsconfig/node14": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
@ -3364,6 +3427,12 @@
|
|||||||
"integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
|
"integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "20.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
|
||||||
|
"integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/normalize-package-data": {
|
"@types/normalize-package-data": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
|
||||||
@ -3961,6 +4030,13 @@
|
|||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@ -4675,6 +4751,12 @@
|
|||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"playwright-core": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-aizyPE1Cj62vAECdph1iaMILpT0WUDCq3E6rW6I+dleSbBoGbktvJtzS6VHkZ4DKNEOG9qJpiom/ZxO+S15LAw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"portfinder": {
|
"portfinder": {
|
||||||
"version": "1.0.32",
|
"version": "1.0.32",
|
||||||
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"format-check": "prettier --check .",
|
"format-check": "prettier --check .",
|
||||||
"lint": "eslint public",
|
"lint": "eslint public",
|
||||||
"lint-styles": "stylelint public/styles/*",
|
"lint-styles": "stylelint public/styles/*",
|
||||||
"serve": "http-server -c-1 public"
|
"serve": "http-server -c-1 public",
|
||||||
|
"test": "playwright test"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -26,6 +27,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/morris/vanilla-todo#readme",
|
"homepage": "https://github.com/morris/vanilla-todo#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.33.0",
|
||||||
"eslint": "^8.20.0",
|
"eslint": "^8.20.0",
|
||||||
"eslint-plugin-compat": "^4.0.2",
|
"eslint-plugin-compat": "^4.0.2",
|
||||||
"http-server": "^14.1.1",
|
"http-server": "^14.1.1",
|
||||||
|
27
test/e2e/addItem.test.mjs
Normal file
27
test/e2e/addItem.test.mjs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
test("Add item to today's todo list (Enter)", async ({ page }) => {
|
||||||
|
await page.goto('http://localhost:8080');
|
||||||
|
|
||||||
|
const input = page.locator('.-today .todo-item-input > input').filter();
|
||||||
|
await input.focus();
|
||||||
|
await input.type('Hello, world!');
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
|
||||||
|
await expect(page.locator('.-today .todo-item > .label')).toHaveText(
|
||||||
|
'Hello, world!'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Add item to today's todo list (click)", async ({ page }) => {
|
||||||
|
await page.goto('http://localhost:8080');
|
||||||
|
|
||||||
|
const input = page.locator('.-today .todo-item-input > input').filter();
|
||||||
|
await input.focus();
|
||||||
|
await input.type('Hello, world!');
|
||||||
|
await page.locator('.-today .todo-item-input > .save').click();
|
||||||
|
|
||||||
|
await expect(page.locator('.-today .todo-item > .label')).toHaveText(
|
||||||
|
'Hello, world!'
|
||||||
|
);
|
||||||
|
});
|
9
test/unit/util.test.mjs
Normal file
9
test/unit/util.test.mjs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
import util from '../../public/scripts/util.js';
|
||||||
|
|
||||||
|
test('formatDate', () => {
|
||||||
|
expect(util.formatDate(new Date(0))).toEqual('January 1st 1970');
|
||||||
|
expect(util.formatDate(new Date('2023-05-13 12:00:00'))).toEqual(
|
||||||
|
'May 13th 2023'
|
||||||
|
);
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user