html-browser-tester 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser-test.d.ts +58 -0
- package/lib/browser-test.js +86 -0
- package/lib/expect/assert.d.ts +15 -0
- package/lib/expect/assert.js +62 -0
- package/lib/expect/index.d.ts +15 -0
- package/lib/expect/index.js +27 -0
- package/lib/main.d.ts +1 -0
- package/lib/main.js +41 -0
- package/package.json +1 -1
- package/.github/release-drafter.yml +0 -22
- package/.github/workflows/pr.yml +0 -47
- package/.github/workflows/publish.yml +0 -53
- package/.github/workflows/version-check.yml +0 -26
- package/index.html +0 -13
- package/src/browser-test.ts +0 -112
- package/src/expect/assert.ts +0 -62
- package/src/expect/index.ts +0 -40
- package/src/main.ts +0 -49
- package/src/vite-env.d.ts +0 -1
- package/utility/version-check.js +0 -10
@@ -0,0 +1,58 @@
|
|
1
|
+
declare type Option = {
|
2
|
+
html: string;
|
3
|
+
width?: number;
|
4
|
+
height?: number;
|
5
|
+
};
|
6
|
+
declare type Result = {
|
7
|
+
description: string;
|
8
|
+
result: boolean;
|
9
|
+
};
|
10
|
+
export declare class BrowserTester {
|
11
|
+
private html;
|
12
|
+
private width?;
|
13
|
+
private height?;
|
14
|
+
private iframe;
|
15
|
+
private tests;
|
16
|
+
private expects;
|
17
|
+
private beforeEachCallbacks;
|
18
|
+
private afterEachCallbacks;
|
19
|
+
constructor({ html, width, height, }: Option);
|
20
|
+
setBrowserSize(width: number, height: number): void;
|
21
|
+
beforeEach(callback: (window: Window, doc: Document) => Promise<void>): void;
|
22
|
+
afterEach(callback: (window: Window, doc: Document) => Promise<void>): void;
|
23
|
+
test(description: string, callback: (window: Window, doc: Document) => Promise<void>): void;
|
24
|
+
expect(value: unknown): {
|
25
|
+
toBe: (value: unknown) => void;
|
26
|
+
toBeTruthy: (value: unknown) => void;
|
27
|
+
toBeFalsy: (value: unknown) => void;
|
28
|
+
toBeNull: (value: unknown) => void;
|
29
|
+
toBeUndefined: (value: unknown) => void;
|
30
|
+
toBeDefined: (value: unknown) => void;
|
31
|
+
toBeNaN: (value: unknown) => void;
|
32
|
+
toContain: (value: unknown) => void;
|
33
|
+
toBeLessThan: (value: unknown) => void;
|
34
|
+
toBeGreaterThan: (value: unknown) => void;
|
35
|
+
toBeLessThanOrEqual: (value: unknown) => void;
|
36
|
+
toBeGreaterThanOrEqual: (value: unknown) => void;
|
37
|
+
toBeInstanceOf: (value: unknown) => void;
|
38
|
+
} & {
|
39
|
+
not: {
|
40
|
+
toBe: (value: unknown) => void;
|
41
|
+
toBeTruthy: (value: unknown) => void;
|
42
|
+
toBeFalsy: (value: unknown) => void;
|
43
|
+
toBeNull: (value: unknown) => void;
|
44
|
+
toBeUndefined: (value: unknown) => void;
|
45
|
+
toBeDefined: (value: unknown) => void;
|
46
|
+
toBeNaN: (value: unknown) => void;
|
47
|
+
toContain: (value: unknown) => void;
|
48
|
+
toBeLessThan: (value: unknown) => void;
|
49
|
+
toBeGreaterThan: (value: unknown) => void;
|
50
|
+
toBeLessThanOrEqual: (value: unknown) => void;
|
51
|
+
toBeGreaterThanOrEqual: (value: unknown) => void;
|
52
|
+
toBeInstanceOf: (value: unknown) => void;
|
53
|
+
};
|
54
|
+
};
|
55
|
+
clearTests(): void;
|
56
|
+
run(): Promise<Result[]>;
|
57
|
+
}
|
58
|
+
export {};
|
@@ -0,0 +1,86 @@
|
|
1
|
+
import { Expect } from "./expect";
|
2
|
+
export class BrowserTester {
|
3
|
+
html = '';
|
4
|
+
width;
|
5
|
+
height;
|
6
|
+
iframe;
|
7
|
+
tests = [];
|
8
|
+
expects = new Expect();
|
9
|
+
beforeEachCallbacks = [];
|
10
|
+
afterEachCallbacks = [];
|
11
|
+
constructor({ html = '', width, height, }) {
|
12
|
+
this.html = html;
|
13
|
+
if (width) {
|
14
|
+
this.width = width;
|
15
|
+
}
|
16
|
+
if (height) {
|
17
|
+
this.height = height;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
setBrowserSize(width, height) {
|
21
|
+
if (width) {
|
22
|
+
this.iframe.width = `${width}px`;
|
23
|
+
}
|
24
|
+
if (height) {
|
25
|
+
this.iframe.height = `${height}px`;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
beforeEach(callback) {
|
29
|
+
this.beforeEachCallbacks.push(callback);
|
30
|
+
}
|
31
|
+
afterEach(callback) {
|
32
|
+
this.afterEachCallbacks.push(callback);
|
33
|
+
}
|
34
|
+
test(description, callback) {
|
35
|
+
this.tests.push({
|
36
|
+
description,
|
37
|
+
callback,
|
38
|
+
});
|
39
|
+
}
|
40
|
+
expect(value) {
|
41
|
+
return this.expects.expect(value);
|
42
|
+
}
|
43
|
+
clearTests() {
|
44
|
+
this.tests = [];
|
45
|
+
}
|
46
|
+
run() {
|
47
|
+
return new Promise((resolve) => {
|
48
|
+
const blob = new Blob([this.html], { type: "text/html" });
|
49
|
+
const url = URL.createObjectURL(blob);
|
50
|
+
const iframe = document.createElement('iframe');
|
51
|
+
const body = document.querySelector('body');
|
52
|
+
this.iframe = iframe;
|
53
|
+
iframe.style.opacity = '0';
|
54
|
+
iframe.style.pointerEvents = 'none';
|
55
|
+
iframe.src = url;
|
56
|
+
if (this.width && this.height) {
|
57
|
+
iframe.width = `${this.width}px`;
|
58
|
+
iframe.height = `${this.height}px`;
|
59
|
+
}
|
60
|
+
const iframeCallback = async () => {
|
61
|
+
const results = [];
|
62
|
+
for (const t of this.tests) {
|
63
|
+
for (const b of this.beforeEachCallbacks) {
|
64
|
+
await b(iframe.contentWindow, iframe.contentDocument);
|
65
|
+
}
|
66
|
+
await t.callback(iframe.contentWindow, iframe.contentDocument);
|
67
|
+
const { description } = t;
|
68
|
+
results.push({
|
69
|
+
description,
|
70
|
+
result: this.expects.isAllPassed()
|
71
|
+
});
|
72
|
+
this.expects.clean();
|
73
|
+
for (const a of this.afterEachCallbacks) {
|
74
|
+
await a(iframe.contentWindow, iframe.contentDocument);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
iframe.removeEventListener('load', iframeCallback);
|
78
|
+
URL.revokeObjectURL(url);
|
79
|
+
iframe.remove();
|
80
|
+
resolve(results);
|
81
|
+
};
|
82
|
+
iframe.addEventListener('load', iframeCallback);
|
83
|
+
body.appendChild(iframe);
|
84
|
+
});
|
85
|
+
}
|
86
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
export declare const assert: (expected: unknown) => {
|
2
|
+
toBe: (resut: unknown) => boolean;
|
3
|
+
toBeTruthy: (result: unknown) => boolean;
|
4
|
+
toBeFalsy: (result: unknown) => boolean;
|
5
|
+
toBeNull: (result: unknown) => boolean;
|
6
|
+
toBeUndefined: (result: unknown) => boolean;
|
7
|
+
toBeDefined: (result: unknown) => boolean;
|
8
|
+
toBeNaN: (result: unknown) => boolean;
|
9
|
+
toContain: (result: unknown) => boolean;
|
10
|
+
toBeLessThan: (result: unknown) => boolean;
|
11
|
+
toBeGreaterThan: (result: unknown) => boolean;
|
12
|
+
toBeLessThanOrEqual: (result: unknown) => boolean;
|
13
|
+
toBeGreaterThanOrEqual: (result: unknown) => boolean;
|
14
|
+
toBeInstanceOf: (result: unknown) => boolean;
|
15
|
+
};
|
@@ -0,0 +1,62 @@
|
|
1
|
+
export const assert = (expected) => ({
|
2
|
+
toBe: (resut) => {
|
3
|
+
return expected === resut;
|
4
|
+
},
|
5
|
+
toBeTruthy: (result) => {
|
6
|
+
return result === true;
|
7
|
+
},
|
8
|
+
toBeFalsy: (result) => {
|
9
|
+
return result === false;
|
10
|
+
},
|
11
|
+
toBeNull: (result) => {
|
12
|
+
return result === null;
|
13
|
+
},
|
14
|
+
toBeUndefined: (result) => {
|
15
|
+
return result === undefined;
|
16
|
+
},
|
17
|
+
toBeDefined: (result) => {
|
18
|
+
return result !== undefined;
|
19
|
+
},
|
20
|
+
toBeNaN: (result) => {
|
21
|
+
return result === NaN;
|
22
|
+
},
|
23
|
+
toContain: (result) => {
|
24
|
+
if (Array.isArray(expected)) {
|
25
|
+
expected.some(item => item === result);
|
26
|
+
}
|
27
|
+
return false;
|
28
|
+
},
|
29
|
+
toBeLessThan: (result) => {
|
30
|
+
if (typeof expected === 'number' && typeof result === 'number') {
|
31
|
+
return expected < result;
|
32
|
+
}
|
33
|
+
return false;
|
34
|
+
},
|
35
|
+
toBeGreaterThan: (result) => {
|
36
|
+
if (typeof expected === 'number' && typeof result === 'number') {
|
37
|
+
return expected > result;
|
38
|
+
}
|
39
|
+
return false;
|
40
|
+
},
|
41
|
+
toBeLessThanOrEqual: (result) => {
|
42
|
+
if (typeof expected === 'number' && typeof result === 'number') {
|
43
|
+
return expected <= result;
|
44
|
+
}
|
45
|
+
return false;
|
46
|
+
},
|
47
|
+
toBeGreaterThanOrEqual: (result) => {
|
48
|
+
if (typeof expected === 'number' && typeof result === 'number') {
|
49
|
+
return expected >= result;
|
50
|
+
}
|
51
|
+
return false;
|
52
|
+
},
|
53
|
+
toBeInstanceOf: (result) => {
|
54
|
+
if (typeof result !== 'function') {
|
55
|
+
return false;
|
56
|
+
}
|
57
|
+
if (expected instanceof result) {
|
58
|
+
return true;
|
59
|
+
}
|
60
|
+
return false;
|
61
|
+
},
|
62
|
+
});
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { assert } from './assert';
|
2
|
+
declare type AssertKey = keyof ReturnType<typeof assert>;
|
3
|
+
declare type TruthyAssertObject = {
|
4
|
+
[T in AssertKey]: (value: unknown) => void;
|
5
|
+
};
|
6
|
+
declare type ReturnObject = TruthyAssertObject & {
|
7
|
+
not: TruthyAssertObject;
|
8
|
+
};
|
9
|
+
export declare class Expect {
|
10
|
+
private expects;
|
11
|
+
expect(expected: unknown): ReturnObject;
|
12
|
+
clean(): void;
|
13
|
+
isAllPassed(): boolean;
|
14
|
+
}
|
15
|
+
export {};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { assert } from './assert';
|
2
|
+
export class Expect {
|
3
|
+
expects = [];
|
4
|
+
expect(expected) {
|
5
|
+
const assertedObject = assert(expected);
|
6
|
+
const returnObject = {
|
7
|
+
not: {},
|
8
|
+
};
|
9
|
+
Object.keys(assertedObject).forEach((key) => {
|
10
|
+
returnObject[key] = (result) => {
|
11
|
+
this.expects.push(assertedObject[key](result));
|
12
|
+
};
|
13
|
+
});
|
14
|
+
Object.keys(assertedObject).forEach((key) => {
|
15
|
+
returnObject.not[key] = (result) => {
|
16
|
+
this.expects.push(!assertedObject[key](result));
|
17
|
+
};
|
18
|
+
});
|
19
|
+
return returnObject;
|
20
|
+
}
|
21
|
+
clean() {
|
22
|
+
this.expects = [];
|
23
|
+
}
|
24
|
+
isAllPassed() {
|
25
|
+
return this.expects.every(e => e);
|
26
|
+
}
|
27
|
+
}
|
package/lib/main.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/lib/main.js
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
import { BrowserTester } from "./browser-test";
|
2
|
+
const html = `
|
3
|
+
<!DOCTYPE html>
|
4
|
+
<html lang="ja">
|
5
|
+
<head>
|
6
|
+
<meta charset="UTF-8">
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
9
|
+
<title>Hello</title>
|
10
|
+
<style>
|
11
|
+
h2 {
|
12
|
+
color: red;
|
13
|
+
}
|
14
|
+
</style>
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<h1>Title1</h1>
|
18
|
+
<h2>Title2</h2>
|
19
|
+
</body>
|
20
|
+
</html>
|
21
|
+
`;
|
22
|
+
const main = async () => {
|
23
|
+
const browserTest = new BrowserTester({ html, width: 980, height: 980 });
|
24
|
+
browserTest.test('h1,h2 textContent should have right textContent', async (_, doc) => {
|
25
|
+
const h1 = doc.querySelector('h1');
|
26
|
+
const h2 = doc.querySelector('h2');
|
27
|
+
browserTest.expect(h1?.textContent).toBe('Title1');
|
28
|
+
browserTest.expect(h2?.textContent).toBe('Title2');
|
29
|
+
});
|
30
|
+
browserTest.test('title should have right textContent', async (_, doc) => {
|
31
|
+
const title = doc.querySelector('title');
|
32
|
+
browserTest.expect(title?.textContent).toBe('Hello');
|
33
|
+
});
|
34
|
+
browserTest.test('h2 should have red text', async (window, doc) => {
|
35
|
+
const h2 = doc.querySelector('h2');
|
36
|
+
browserTest.expect(window.getComputedStyle(h2).color).toBe('rgb(255, 0, 0)');
|
37
|
+
});
|
38
|
+
const results = await browserTest.run();
|
39
|
+
console.log(results);
|
40
|
+
};
|
41
|
+
main();
|
package/package.json
CHANGED
@@ -1,22 +0,0 @@
|
|
1
|
-
name-template: 'v$RESOLVED_VERSION 🌈'
|
2
|
-
tag-template: 'v$RESOLVED_VERSION'
|
3
|
-
exclude-labels:
|
4
|
-
- 'release'
|
5
|
-
- 'auto'
|
6
|
-
categories:
|
7
|
-
- title: '🚀 Features'
|
8
|
-
labels:
|
9
|
-
- 'feature'
|
10
|
-
- 'enhancement'
|
11
|
-
- title: '🐛 Bug Fixes'
|
12
|
-
labels:
|
13
|
-
- 'fix'
|
14
|
-
- 'bugfix'
|
15
|
-
- 'bug'
|
16
|
-
- title: '🧰 Maintenance'
|
17
|
-
label: 'chore'
|
18
|
-
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
19
|
-
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
20
|
-
template: |
|
21
|
-
## Changes
|
22
|
-
$CHANGES
|
package/.github/workflows/pr.yml
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
name: PR
|
2
|
-
env:
|
3
|
-
CI: true
|
4
|
-
# preview環境更新および、stage環境やproduction環境の更新を行うworkflow
|
5
|
-
on:
|
6
|
-
push:
|
7
|
-
branches:
|
8
|
-
- master
|
9
|
-
- develop
|
10
|
-
pull_request:
|
11
|
-
branches:
|
12
|
-
- master
|
13
|
-
- develop
|
14
|
-
types:
|
15
|
-
- opened
|
16
|
-
- synchronize
|
17
|
-
- closed
|
18
|
-
- labeled
|
19
|
-
- unlabeled
|
20
|
-
tags:
|
21
|
-
- "!*"
|
22
|
-
jobs:
|
23
|
-
release:
|
24
|
-
name: Setup
|
25
|
-
runs-on: ubuntu-latest
|
26
|
-
steps:
|
27
|
-
- name: check label
|
28
|
-
if: |
|
29
|
-
github.event_name == 'pull_request' &&
|
30
|
-
!contains(github.event.pull_request.labels.*.name, 'fix') &&
|
31
|
-
!contains(github.event.pull_request.labels.*.name, 'bugfix') &&
|
32
|
-
!contains(github.event.pull_request.labels.*.name, 'enhancement') &&
|
33
|
-
!contains(github.event.pull_request.labels.*.name, 'chore') &&
|
34
|
-
!contains(github.event.pull_request.labels.*.name, 'feature') &&
|
35
|
-
!contains(github.event.pull_request.labels.*.name, 'release') &&
|
36
|
-
!contains(github.event.pull_request.labels.*.name, 'auto')
|
37
|
-
env:
|
38
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
39
|
-
URL: ${{ github.event.pull_request.comments_url }}
|
40
|
-
run: |
|
41
|
-
echo "Please add one of the following labels: fix, bugfix, enhancement, chore, feature, release" >> comments
|
42
|
-
sed -i -z 's/\n/\\n/g' comments
|
43
|
-
curl -X POST \
|
44
|
-
-H "Authorization: token ${GITHUB_TOKEN}" \
|
45
|
-
-d "{\"body\": \"$(cat comments)\"}" \
|
46
|
-
${URL}
|
47
|
-
exit 1
|
@@ -1,53 +0,0 @@
|
|
1
|
-
name: Publish
|
2
|
-
env:
|
3
|
-
CI: true
|
4
|
-
# masterブランチにpushした時のみ実行するワークフロー
|
5
|
-
on:
|
6
|
-
push:
|
7
|
-
branches:
|
8
|
-
- master
|
9
|
-
tags:
|
10
|
-
- "!*"
|
11
|
-
|
12
|
-
jobs:
|
13
|
-
release:
|
14
|
-
name: Setup
|
15
|
-
runs-on: ubuntu-latest
|
16
|
-
steps:
|
17
|
-
- name: checkout
|
18
|
-
uses: actions/checkout@v1
|
19
|
-
- name: setup Node
|
20
|
-
uses: actions/setup-node@v1
|
21
|
-
with:
|
22
|
-
node-version: 16.x
|
23
|
-
registry-url: 'https://registry.npmjs.org'
|
24
|
-
- name: install
|
25
|
-
run: yarn --frozen-lockfile
|
26
|
-
# まだtagがないバージョンなら、Git Tagをpushする
|
27
|
-
- name: package-version
|
28
|
-
run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
|
29
|
-
- name: package-version-to-git-tag
|
30
|
-
uses: pkgdeps/action-package-version-to-git-tag@v1
|
31
|
-
with:
|
32
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
33
|
-
github_repo: ${{ github.repository }}
|
34
|
-
git_commit_sha: ${{ github.sha }}
|
35
|
-
git_tag_prefix: ""
|
36
|
-
version: ${{ env.PACKAGE_VERSION }}
|
37
|
-
- name: get-npm-version
|
38
|
-
id: package-version
|
39
|
-
uses: martinbeentjes/npm-get-version-action@master
|
40
|
-
- name: create draft
|
41
|
-
uses: release-drafter/release-drafter@v5
|
42
|
-
with:
|
43
|
-
version: ${{ steps.package-version.outputs.current-version }}
|
44
|
-
name: ${{ steps.package-version.outputs.current-version }}
|
45
|
-
tag: ${{ steps.package-version.outputs.current-version }}
|
46
|
-
env:
|
47
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
48
|
-
- name: build lib
|
49
|
-
run: npm run build:lib
|
50
|
-
- name: publish to npm
|
51
|
-
run: npm publish
|
52
|
-
env:
|
53
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
@@ -1,26 +0,0 @@
|
|
1
|
-
name: Version Check
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
branches:
|
5
|
-
- master
|
6
|
-
types:
|
7
|
-
- opened
|
8
|
-
- synchronize
|
9
|
-
|
10
|
-
jobs:
|
11
|
-
auto-bumping:
|
12
|
-
runs-on: ubuntu-latest
|
13
|
-
steps:
|
14
|
-
- name: checkout
|
15
|
-
uses: actions/checkout@v1
|
16
|
-
- name: setup Node
|
17
|
-
uses: actions/setup-node@v1
|
18
|
-
with:
|
19
|
-
node-version: 16.x
|
20
|
-
registry-url: 'https://npm.pkg.github.com'
|
21
|
-
- name: install
|
22
|
-
run: yarn --frozen-lockfile
|
23
|
-
- name: version check
|
24
|
-
run: BRANCH_NAME=$HEAD_BRANCH node ./utility/version-check.js
|
25
|
-
env:
|
26
|
-
HEAD_BRANCH: ${{ github.head_ref }}
|
package/index.html
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html lang="en">
|
3
|
-
<head>
|
4
|
-
<meta charset="UTF-8" />
|
5
|
-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
7
|
-
<title>Vite + TS</title>
|
8
|
-
</head>
|
9
|
-
<body>
|
10
|
-
<div id="app"></div>
|
11
|
-
<script type="module" src="/src/main.ts"></script>
|
12
|
-
</body>
|
13
|
-
</html>
|
package/src/browser-test.ts
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
import { Expect } from "./expect";
|
2
|
-
|
3
|
-
type Option = {
|
4
|
-
html: string;
|
5
|
-
width?: number;
|
6
|
-
height?: number;
|
7
|
-
}
|
8
|
-
|
9
|
-
type Result = {
|
10
|
-
description: string;
|
11
|
-
result: boolean;
|
12
|
-
}
|
13
|
-
|
14
|
-
type Test = {
|
15
|
-
description: string;
|
16
|
-
callback: (window: Window, doc: Document) => Promise<void>
|
17
|
-
}
|
18
|
-
|
19
|
-
export class BrowserTester {
|
20
|
-
private html = '';
|
21
|
-
private width?: number;
|
22
|
-
private height?: number;
|
23
|
-
private iframe!: HTMLIFrameElement;
|
24
|
-
private tests: Test[] = []
|
25
|
-
private expects = new Expect()
|
26
|
-
private beforeEachCallbacks: ((window: Window, doc: Document) => Promise<void>)[] = []
|
27
|
-
private afterEachCallbacks: ((window: Window, doc: Document) => Promise<void>)[] = []
|
28
|
-
|
29
|
-
constructor({
|
30
|
-
html = '',
|
31
|
-
width,
|
32
|
-
height,
|
33
|
-
}: Option) {
|
34
|
-
this.html = html
|
35
|
-
if (width) {
|
36
|
-
this.width = width
|
37
|
-
}
|
38
|
-
if (height) {
|
39
|
-
this.height = height
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
setBrowserSize(width: number, height: number) {
|
44
|
-
if (width) {
|
45
|
-
this.iframe.width = `${width}px`
|
46
|
-
}
|
47
|
-
if (height) {
|
48
|
-
this.iframe.height = `${height}px`
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
beforeEach(callback: (window: Window, doc: Document) => Promise<void>) {
|
53
|
-
this.beforeEachCallbacks.push(callback)
|
54
|
-
}
|
55
|
-
|
56
|
-
afterEach(callback: (window: Window, doc: Document) => Promise<void>) {
|
57
|
-
this.afterEachCallbacks.push(callback)
|
58
|
-
}
|
59
|
-
|
60
|
-
test(description: string, callback: (window: Window, doc: Document) => Promise<void>) {
|
61
|
-
this.tests.push({
|
62
|
-
description,
|
63
|
-
callback,
|
64
|
-
})
|
65
|
-
}
|
66
|
-
|
67
|
-
expect(value: unknown) {
|
68
|
-
return this.expects.expect(value)
|
69
|
-
}
|
70
|
-
|
71
|
-
run() {
|
72
|
-
return new Promise<Result[]>((resolve) => {
|
73
|
-
const blob = new Blob(
|
74
|
-
[this.html],
|
75
|
-
{ type: "text/html" }
|
76
|
-
);
|
77
|
-
const url = URL.createObjectURL(blob);
|
78
|
-
const iframe = document.createElement('iframe')
|
79
|
-
const body = document.querySelector('body') as HTMLBodyElement
|
80
|
-
this.iframe = iframe
|
81
|
-
iframe.src = url
|
82
|
-
if (this.width && this.height) {
|
83
|
-
iframe.width = `${this.width}px`
|
84
|
-
iframe.height = `${this.height}px`
|
85
|
-
}
|
86
|
-
const iframeCallback = async () => {
|
87
|
-
const results: Result[] = []
|
88
|
-
for (const t of this.tests) {
|
89
|
-
for (const b of this.beforeEachCallbacks) {
|
90
|
-
await b(iframe.contentWindow as Window, iframe.contentDocument as Document)
|
91
|
-
}
|
92
|
-
await t.callback(iframe.contentWindow as Window, iframe.contentDocument as Document)
|
93
|
-
const { description } = t
|
94
|
-
results.push({
|
95
|
-
description,
|
96
|
-
result: this.expects.isAllPassed()
|
97
|
-
})
|
98
|
-
this.expects.clean()
|
99
|
-
for (const a of this.afterEachCallbacks) {
|
100
|
-
await a(iframe.contentWindow as Window, iframe.contentDocument as Document)
|
101
|
-
}
|
102
|
-
}
|
103
|
-
iframe.removeEventListener('load', iframeCallback)
|
104
|
-
URL.revokeObjectURL(url)
|
105
|
-
iframe.remove()
|
106
|
-
resolve(results)
|
107
|
-
}
|
108
|
-
iframe.addEventListener('load', iframeCallback)
|
109
|
-
body.appendChild(iframe)
|
110
|
-
})
|
111
|
-
}
|
112
|
-
}
|
package/src/expect/assert.ts
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
export const assert = (expected: unknown) => ({
|
2
|
-
toBe: (resut: unknown) => {
|
3
|
-
return expected === resut
|
4
|
-
},
|
5
|
-
toBeTruthy: (result: unknown) => {
|
6
|
-
return result === true
|
7
|
-
},
|
8
|
-
toBeFalsy: (result: unknown) => {
|
9
|
-
return result === false
|
10
|
-
},
|
11
|
-
toBeNull: (result: unknown) => {
|
12
|
-
return result === null
|
13
|
-
},
|
14
|
-
toBeUndefined: (result: unknown) => {
|
15
|
-
return result === undefined
|
16
|
-
},
|
17
|
-
toBeDefined: (result: unknown) => {
|
18
|
-
return result !== undefined
|
19
|
-
},
|
20
|
-
toBeNaN: (result: unknown) => {
|
21
|
-
return result === NaN
|
22
|
-
},
|
23
|
-
toContain: (result: unknown) => {
|
24
|
-
if (Array.isArray(expected)) {
|
25
|
-
expected.some(item => item === result)
|
26
|
-
}
|
27
|
-
return false
|
28
|
-
},
|
29
|
-
toBeLessThan: (result: unknown) => {
|
30
|
-
if (typeof expected === 'number' && typeof result === 'number') {
|
31
|
-
return expected < result
|
32
|
-
}
|
33
|
-
return false
|
34
|
-
},
|
35
|
-
toBeGreaterThan: (result: unknown) => {
|
36
|
-
if (typeof expected === 'number' && typeof result === 'number') {
|
37
|
-
return expected > result
|
38
|
-
}
|
39
|
-
return false
|
40
|
-
},
|
41
|
-
toBeLessThanOrEqual: (result: unknown) => {
|
42
|
-
if (typeof expected === 'number' && typeof result === 'number') {
|
43
|
-
return expected <= result
|
44
|
-
}
|
45
|
-
return false
|
46
|
-
},
|
47
|
-
toBeGreaterThanOrEqual: (result: unknown) => {
|
48
|
-
if (typeof expected === 'number' && typeof result === 'number') {
|
49
|
-
return expected >= result
|
50
|
-
}
|
51
|
-
return false
|
52
|
-
},
|
53
|
-
toBeInstanceOf: (result: unknown) => {
|
54
|
-
if (typeof result !== 'function') {
|
55
|
-
return false
|
56
|
-
}
|
57
|
-
if (expected instanceof result) {
|
58
|
-
return true
|
59
|
-
}
|
60
|
-
return false
|
61
|
-
},
|
62
|
-
})
|
package/src/expect/index.ts
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
import { assert } from './assert';
|
2
|
-
|
3
|
-
type AssertKey = keyof ReturnType<typeof assert>
|
4
|
-
type TruthyAssertObject = { [T in AssertKey]: (value: unknown) => void }
|
5
|
-
|
6
|
-
type ReturnObject =
|
7
|
-
TruthyAssertObject
|
8
|
-
& {
|
9
|
-
not: TruthyAssertObject
|
10
|
-
}
|
11
|
-
|
12
|
-
export class Expect {
|
13
|
-
private expects: boolean[] = []
|
14
|
-
|
15
|
-
expect(expected: unknown) {
|
16
|
-
const assertedObject = assert(expected)
|
17
|
-
const returnObject = {
|
18
|
-
not: {},
|
19
|
-
} as ReturnObject;
|
20
|
-
(Object.keys(assertedObject) as AssertKey[]).forEach((key) => {
|
21
|
-
returnObject[key] = (result: unknown) => {
|
22
|
-
this.expects.push(assertedObject[key](result))
|
23
|
-
}
|
24
|
-
})
|
25
|
-
;(Object.keys(assertedObject) as AssertKey[]).forEach((key) => {
|
26
|
-
returnObject.not[key] = (result: unknown) => {
|
27
|
-
this.expects.push(!assertedObject[key](result))
|
28
|
-
}
|
29
|
-
})
|
30
|
-
return returnObject;
|
31
|
-
}
|
32
|
-
|
33
|
-
clean() {
|
34
|
-
this.expects = []
|
35
|
-
}
|
36
|
-
|
37
|
-
isAllPassed() {
|
38
|
-
return this.expects.every(e => e)
|
39
|
-
}
|
40
|
-
}
|
package/src/main.ts
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
import { BrowserTester } from "./browser-test";
|
2
|
-
|
3
|
-
const html = `
|
4
|
-
<!DOCTYPE html>
|
5
|
-
<html lang="ja">
|
6
|
-
<head>
|
7
|
-
<meta charset="UTF-8">
|
8
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
9
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
10
|
-
<title>Hello</title>
|
11
|
-
<style>
|
12
|
-
h2 {
|
13
|
-
color: red;
|
14
|
-
}
|
15
|
-
</style>
|
16
|
-
</head>
|
17
|
-
<body>
|
18
|
-
<h1>Title1</h1>
|
19
|
-
<h2>Title2</h2>
|
20
|
-
</body>
|
21
|
-
</html>
|
22
|
-
`
|
23
|
-
|
24
|
-
const main = async () => {
|
25
|
-
const browserTest = new BrowserTester({ html, width: 980, height: 980 })
|
26
|
-
|
27
|
-
browserTest.test('h1,h2 textContent should have right textContent', async (_, doc) => {
|
28
|
-
const h1 = doc.querySelector('h1')
|
29
|
-
const h2 = doc.querySelector('h2')
|
30
|
-
browserTest.expect(h1?.textContent).toBe('Title1')
|
31
|
-
browserTest.expect(h2?.textContent).toBe('Title2')
|
32
|
-
})
|
33
|
-
|
34
|
-
browserTest.test('title should have right textContent', async (_, doc) => {
|
35
|
-
const title = doc.querySelector('title')
|
36
|
-
browserTest.expect(title?.textContent).toBe('Hello')
|
37
|
-
})
|
38
|
-
|
39
|
-
browserTest.test('h2 should have red text', async (window, doc) => {
|
40
|
-
const h2 = doc.querySelector('h2') as HTMLHeadingElement
|
41
|
-
browserTest.expect(window.getComputedStyle(h2).color).toBe('rgb(255, 0, 0)')
|
42
|
-
})
|
43
|
-
|
44
|
-
const results = await browserTest.run()
|
45
|
-
|
46
|
-
console.log(results)
|
47
|
-
}
|
48
|
-
|
49
|
-
main()
|
package/src/vite-env.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
/// <reference types="vite/client" />
|
package/utility/version-check.js
DELETED