@rvoh/psychic-spec-helpers 0.3.1-fgbeta-9 → 0.4.0
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/dist/esm/src/feature/helpers/{launchViteServer.js → launchDevServer.js} +25 -20
- package/dist/esm/src/feature/helpers/metaOrControlKey.js +4 -0
- package/dist/esm/src/feature/helpers/providePuppeteerViteMatchers.js +26 -26
- package/dist/esm/src/feature/helpers/visit.js +0 -1
- package/dist/esm/src/feature/matchers/toCheck.js +15 -20
- package/dist/esm/src/feature/matchers/toClick.js +3 -3
- package/dist/esm/src/feature/matchers/toClickButton.js +14 -21
- package/dist/esm/src/feature/matchers/toClickLink.js +14 -21
- package/dist/esm/src/feature/matchers/toClickSelector.js +14 -21
- package/dist/esm/src/feature/matchers/toFill.js +25 -16
- package/dist/esm/src/feature/matchers/toHaveChecked.js +13 -14
- package/dist/esm/src/feature/matchers/toHaveLink.js +14 -22
- package/dist/esm/src/feature/matchers/toHavePath.js +3 -1
- package/dist/esm/src/feature/matchers/toHaveSelector.js +2 -2
- package/dist/esm/src/feature/matchers/toHaveUnchecked.js +13 -14
- package/dist/esm/src/feature/matchers/toNotHaveSelector.js +14 -13
- package/dist/esm/src/feature/matchers/toUncheck.js +22 -19
- package/dist/esm/src/index.js +1 -1
- package/dist/types/src/feature/helpers/launchDevServer.d.ts +7 -0
- package/dist/types/src/feature/helpers/metaOrControlKey.d.ts +1 -0
- package/dist/types/src/feature/helpers/visit.d.ts +1 -1
- package/dist/types/src/feature/matchers/toCheck.d.ts +6 -3
- package/dist/types/src/feature/matchers/toClick.d.ts +2 -2
- package/dist/types/src/feature/matchers/toClickButton.d.ts +6 -3
- package/dist/types/src/feature/matchers/toClickLink.d.ts +6 -3
- package/dist/types/src/feature/matchers/toClickSelector.d.ts +6 -3
- package/dist/types/src/feature/matchers/toFill.d.ts +6 -3
- package/dist/types/src/feature/matchers/toHaveChecked.d.ts +6 -3
- package/dist/types/src/feature/matchers/toHaveLink.d.ts +3 -3
- package/dist/types/src/feature/matchers/toHaveSelector.d.ts +2 -2
- package/dist/types/src/feature/matchers/toHaveUnchecked.d.ts +3 -3
- package/dist/types/src/feature/matchers/toMatchTextContent.d.ts +2 -2
- package/dist/types/src/feature/matchers/toNotHaveSelector.d.ts +3 -3
- package/dist/types/src/feature/matchers/toUncheck.d.ts +8 -2
- package/dist/types/src/index.d.ts +15 -14
- package/package.json +1 -2
- package/src/feature/helpers/{launchViteServer.ts → launchDevServer.ts} +35 -25
- package/src/feature/helpers/metaOrControlKey.ts +4 -0
- package/src/feature/helpers/providePuppeteerViteMatchers.ts +32 -28
- package/src/feature/helpers/visit.ts +0 -1
- package/src/feature/matchers/toCheck.ts +20 -30
- package/src/feature/matchers/toClick.ts +8 -7
- package/src/feature/matchers/toClickButton.ts +20 -25
- package/src/feature/matchers/toClickLink.ts +20 -25
- package/src/feature/matchers/toClickSelector.ts +20 -25
- package/src/feature/matchers/toFill.ts +36 -23
- package/src/feature/matchers/toHaveChecked.ts +23 -22
- package/src/feature/matchers/toHaveLink.ts +19 -27
- package/src/feature/matchers/toHavePath.ts +3 -1
- package/src/feature/matchers/toHaveSelector.ts +7 -3
- package/src/feature/matchers/toHaveUnchecked.ts +23 -22
- package/src/feature/matchers/toMatchTextContent.ts +2 -2
- package/src/feature/matchers/toNotHaveSelector.ts +17 -18
- package/src/feature/matchers/toUncheck.ts +28 -29
- package/src/index.ts +19 -14
- package/dist/types/src/feature/helpers/launchViteServer.d.ts +0 -6
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { createServer } from 'net';
|
|
3
3
|
import sleep from '../../shared/sleep.js';
|
|
4
|
-
|
|
5
|
-
export default async function
|
|
6
|
-
if (
|
|
4
|
+
const devServerProcesses = {};
|
|
5
|
+
export default async function launchDevServer(key, { port = 3000, cmd = 'yarn client', timeout = 5000, } = {}) {
|
|
6
|
+
if (devServerProcesses[key])
|
|
7
7
|
return;
|
|
8
8
|
if (process.env.DEBUG === '1')
|
|
9
9
|
console.log('Starting server...');
|
|
10
10
|
const [_cmd, ...args] = cmd.split(' ');
|
|
11
|
-
|
|
11
|
+
const proc = spawn(_cmd, args, {
|
|
12
12
|
detached: true,
|
|
13
13
|
env: {
|
|
14
14
|
...process.env,
|
|
@@ -16,41 +16,46 @@ export default async function launchViteServer({ port = 3000, cmd = 'yarn client
|
|
|
16
16
|
VITE_PSYCHIC_ENV: 'test',
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
|
-
await waitForPort(port, timeout);
|
|
20
|
-
|
|
21
|
-
if (process.env.DEBUG === '1')
|
|
22
|
-
console.log(`Server output: ${data}`);
|
|
23
|
-
});
|
|
24
|
-
serverProcess.on('error', err => {
|
|
19
|
+
await waitForPort(key, port, timeout);
|
|
20
|
+
proc.on('error', err => {
|
|
25
21
|
throw err;
|
|
26
22
|
});
|
|
27
|
-
|
|
23
|
+
proc.stdout.on('data', data => {
|
|
28
24
|
if (process.env.DEBUG === '1')
|
|
29
25
|
console.log(`Server output: ${data}`);
|
|
30
26
|
});
|
|
31
|
-
|
|
27
|
+
proc.stderr.on('data', data => {
|
|
32
28
|
if (process.env.DEBUG === '1')
|
|
33
29
|
console.error(`Server error: ${data}`);
|
|
34
30
|
});
|
|
35
|
-
|
|
31
|
+
proc.on('error', err => {
|
|
36
32
|
console.error(`Server process error: ${err}`);
|
|
37
33
|
});
|
|
38
|
-
|
|
34
|
+
proc.on('close', code => {
|
|
39
35
|
if (process.env.DEBUG === '1')
|
|
40
36
|
console.log(`Server process exited with code ${code}`);
|
|
41
37
|
});
|
|
42
38
|
}
|
|
43
|
-
export function
|
|
44
|
-
|
|
39
|
+
export function stopDevServer(key) {
|
|
40
|
+
const proc = devServerProcesses[key];
|
|
41
|
+
if (!proc) {
|
|
42
|
+
throw new Error(`Cannot find a dev server by the key: ${key}`);
|
|
43
|
+
}
|
|
44
|
+
if (proc?.pid) {
|
|
45
45
|
if (process.env.DEBUG === '1')
|
|
46
46
|
console.log('Stopping server...');
|
|
47
47
|
// serverProcess.kill('SIGINT')
|
|
48
|
-
process.kill(-
|
|
49
|
-
|
|
48
|
+
process.kill(-proc.pid, 'SIGKILL');
|
|
49
|
+
delete devServerProcesses[key];
|
|
50
50
|
if (process.env.DEBUG === '1')
|
|
51
51
|
console.log('server stopped');
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
export function stopDevServers() {
|
|
55
|
+
Object.keys(devServerProcesses).forEach(key => {
|
|
56
|
+
stopDevServer(key);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
54
59
|
async function isPortAvailable(port) {
|
|
55
60
|
return new Promise(resolve => {
|
|
56
61
|
const server = createServer()
|
|
@@ -69,7 +74,7 @@ async function isPortAvailable(port) {
|
|
|
69
74
|
.listen(port, '127.0.0.1');
|
|
70
75
|
});
|
|
71
76
|
}
|
|
72
|
-
async function waitForPort(port, timeout = 5000) {
|
|
77
|
+
async function waitForPort(key, port, timeout = 5000) {
|
|
73
78
|
if (await isPortAvailable(port)) {
|
|
74
79
|
return true;
|
|
75
80
|
}
|
|
@@ -79,7 +84,7 @@ async function waitForPort(port, timeout = 5000) {
|
|
|
79
84
|
return true;
|
|
80
85
|
}
|
|
81
86
|
if (Date.now() > startTime + timeout) {
|
|
82
|
-
|
|
87
|
+
stopDevServer(key);
|
|
83
88
|
throw new Error('waited too long for port: ' + port);
|
|
84
89
|
}
|
|
85
90
|
await sleep(50);
|
|
@@ -18,32 +18,32 @@ import toFill from '../matchers/toFill.js';
|
|
|
18
18
|
export default function providePuppeteerViteMatchers() {
|
|
19
19
|
;
|
|
20
20
|
global.expect.extend({
|
|
21
|
-
async toMatchTextContent(page, text) {
|
|
22
|
-
return await toMatchTextContent(page, text);
|
|
21
|
+
async toMatchTextContent(page, text, opts) {
|
|
22
|
+
return await toMatchTextContent(page, text, opts);
|
|
23
23
|
},
|
|
24
24
|
async toNotMatchTextContent(page, text) {
|
|
25
25
|
return await toNotMatchTextContent(page, text);
|
|
26
26
|
},
|
|
27
|
-
async toHaveSelector(page, cssSelector) {
|
|
28
|
-
return await toHaveSelector(page, cssSelector);
|
|
27
|
+
async toHaveSelector(page, cssSelector, opts) {
|
|
28
|
+
return await toHaveSelector(page, cssSelector, opts);
|
|
29
29
|
},
|
|
30
|
-
async toNotHaveSelector(page, cssSelector) {
|
|
31
|
-
return await toNotHaveSelector(page, cssSelector);
|
|
30
|
+
async toNotHaveSelector(page, cssSelector, opts) {
|
|
31
|
+
return await toNotHaveSelector(page, cssSelector, opts);
|
|
32
32
|
},
|
|
33
|
-
async toCheck(page, text) {
|
|
34
|
-
return await toCheck(page, text);
|
|
33
|
+
async toCheck(page, text, opts) {
|
|
34
|
+
return await toCheck(page, text, opts);
|
|
35
35
|
},
|
|
36
|
-
async toClick(page, text) {
|
|
37
|
-
return await toClick(page, text);
|
|
36
|
+
async toClick(page, text, opts) {
|
|
37
|
+
return await toClick(page, text, opts);
|
|
38
38
|
},
|
|
39
|
-
async toClickLink(page, text) {
|
|
40
|
-
return await toClickLink(page, text);
|
|
39
|
+
async toClickLink(page, text, opts) {
|
|
40
|
+
return await toClickLink(page, text, opts);
|
|
41
41
|
},
|
|
42
|
-
async toClickButton(page, text) {
|
|
43
|
-
return await toClickButton(page, text);
|
|
42
|
+
async toClickButton(page, text, opts) {
|
|
43
|
+
return await toClickButton(page, text, opts);
|
|
44
44
|
},
|
|
45
|
-
async toClickSelector(page, cssSelector) {
|
|
46
|
-
return await toClickSelector(page, cssSelector);
|
|
45
|
+
async toClickSelector(page, cssSelector, opts) {
|
|
46
|
+
return await toClickSelector(page, cssSelector, opts);
|
|
47
47
|
},
|
|
48
48
|
async toHavePath(page, path) {
|
|
49
49
|
return await toHavePath(page, path);
|
|
@@ -51,20 +51,20 @@ export default function providePuppeteerViteMatchers() {
|
|
|
51
51
|
async toHaveUrl(page, url) {
|
|
52
52
|
return await toHaveUrl(page, url);
|
|
53
53
|
},
|
|
54
|
-
async toHaveChecked(page, text) {
|
|
55
|
-
return await toHaveChecked(page, text);
|
|
54
|
+
async toHaveChecked(page, text, opts) {
|
|
55
|
+
return await toHaveChecked(page, text, opts);
|
|
56
56
|
},
|
|
57
|
-
async toHaveUnchecked(page, checked) {
|
|
58
|
-
return await toHaveUnchecked(page, checked);
|
|
57
|
+
async toHaveUnchecked(page, checked, opts) {
|
|
58
|
+
return await toHaveUnchecked(page, checked, opts);
|
|
59
59
|
},
|
|
60
|
-
async toHaveLink(page, text) {
|
|
61
|
-
return await toHaveLink(page, text);
|
|
60
|
+
async toHaveLink(page, text, opts) {
|
|
61
|
+
return await toHaveLink(page, text, opts);
|
|
62
62
|
},
|
|
63
|
-
async toFill(page, cssSelector, text) {
|
|
64
|
-
return await toFill(page, cssSelector, text);
|
|
63
|
+
async toFill(page, cssSelector, text, opts) {
|
|
64
|
+
return await toFill(page, cssSelector, text, opts);
|
|
65
65
|
},
|
|
66
|
-
async toUncheck(page, text) {
|
|
67
|
-
return await toUncheck(page, text);
|
|
66
|
+
async toUncheck(page, text, opts) {
|
|
67
|
+
return await toUncheck(page, text, opts);
|
|
68
68
|
},
|
|
69
69
|
async toEvaluate(argumentPassedToExpect, evaluationFn, opts) {
|
|
70
70
|
return await evaluateWithRetryAndTimeout(argumentPassedToExpect, evaluationFn, opts);
|
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
6
|
-
requirePuppeteerPage(page);
|
|
7
|
-
const checkbox = await page.$(`input[type="checkbox"][value="${expectedText}"]`);
|
|
8
|
-
if (!checkbox)
|
|
9
|
-
return evaluationFailure(`A checkbox was not found with "${expectedText}"`);
|
|
10
|
-
const isChecked = await page.evaluate(checkbox => checkbox.checked, checkbox);
|
|
11
|
-
if (isChecked)
|
|
12
|
-
return evaluationFailure(`A checkbox was found with "${expectedText}", but it is already checked`);
|
|
13
|
-
await checkbox.click();
|
|
14
|
-
const isCheckedNow = await page.evaluate(checkbox => checkbox.checked, checkbox);
|
|
1
|
+
export default async function toCheck(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const el = await page.waitForSelector(`label::-p-text(${expectedText}`, opts);
|
|
4
|
+
await el.click();
|
|
15
5
|
return {
|
|
16
|
-
pass:
|
|
17
|
-
|
|
6
|
+
pass: true,
|
|
7
|
+
message: () => {
|
|
8
|
+
throw new Error('Cannot negate toCheck');
|
|
9
|
+
},
|
|
18
10
|
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return {
|
|
14
|
+
pass: false,
|
|
15
|
+
message: `Expected page to have checkable element with text: "${expectedText}"`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
23
18
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export default async function toClick(page, expectedText) {
|
|
1
|
+
export default async function toClick(page, expectedText, opts) {
|
|
2
2
|
try {
|
|
3
|
-
const el = await page.waitForSelector(`*::-p-text(${expectedText})
|
|
3
|
+
const el = await page.waitForSelector(`*::-p-text(${expectedText})`, opts);
|
|
4
4
|
await el.click();
|
|
5
5
|
return {
|
|
6
6
|
pass: true,
|
|
7
7
|
message: () => {
|
|
8
|
-
throw new Error('Cannot negate
|
|
8
|
+
throw new Error('Cannot negate toClick');
|
|
9
9
|
},
|
|
10
10
|
};
|
|
11
11
|
}
|
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export default async function toClickButton(page, expectedText) {
|
|
6
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
7
|
-
requirePuppeteerPage(page);
|
|
8
|
-
try {
|
|
9
|
-
;
|
|
10
|
-
(await page.$('button::-p-text(Submit)')).click();
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
if (err instanceof TimeoutError)
|
|
14
|
-
return evaluationFailure(expectedText);
|
|
15
|
-
throw err;
|
|
16
|
-
}
|
|
1
|
+
export default async function toClickButton(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const el = await page.waitForSelector('button::-p-text(Submit)', opts);
|
|
4
|
+
await el.click();
|
|
17
5
|
return {
|
|
18
6
|
pass: true,
|
|
19
|
-
|
|
7
|
+
message: () => {
|
|
8
|
+
throw new Error('Cannot negate toClickLink');
|
|
9
|
+
},
|
|
20
10
|
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return {
|
|
14
|
+
pass: false,
|
|
15
|
+
message: `Expected page to have clickable link with matching text: "${expectedText}"`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
25
18
|
}
|
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export default async function toClickLink(page, expectedText) {
|
|
6
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
7
|
-
requirePuppeteerPage(page);
|
|
8
|
-
try {
|
|
9
|
-
;
|
|
10
|
-
(await page.$(`a ::-p-text(${expectedText})`)).click();
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
if (err instanceof TimeoutError)
|
|
14
|
-
return evaluationFailure(expectedText);
|
|
15
|
-
throw err;
|
|
16
|
-
}
|
|
1
|
+
export default async function toClickLink(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const el = await page.waitForSelector(`a ::-p-text(${expectedText})`, opts);
|
|
4
|
+
await el.click();
|
|
17
5
|
return {
|
|
18
6
|
pass: true,
|
|
19
|
-
|
|
7
|
+
message: () => {
|
|
8
|
+
throw new Error('Cannot negate toClickLink');
|
|
9
|
+
},
|
|
20
10
|
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return {
|
|
14
|
+
pass: false,
|
|
15
|
+
message: `Expected page to have clickable link with matching text: "${expectedText}"`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
25
18
|
}
|
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export default async function toClickSelector(page, cssSelector) {
|
|
6
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
7
|
-
requirePuppeteerPage(page);
|
|
8
|
-
try {
|
|
9
|
-
;
|
|
10
|
-
(await page.$(cssSelector)).click();
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
if (err instanceof TimeoutError)
|
|
14
|
-
return evaluationFailure(cssSelector);
|
|
15
|
-
throw err;
|
|
16
|
-
}
|
|
1
|
+
export default async function toClickSelector(page, cssSelector, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const el = await page.waitForSelector(cssSelector, opts);
|
|
4
|
+
await el.click();
|
|
17
5
|
return {
|
|
18
6
|
pass: true,
|
|
19
|
-
|
|
7
|
+
message: () => {
|
|
8
|
+
throw new Error('Cannot negate toNotMatchTextContent, use toMatchTextContent instead');
|
|
9
|
+
},
|
|
20
10
|
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return {
|
|
14
|
+
pass: false,
|
|
15
|
+
message: `Expected page to have clickable element with matching selector: "${cssSelector}"`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
25
18
|
}
|
|
@@ -1,21 +1,30 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import metaOrControlKey from '../helpers/metaOrControlKey.js';
|
|
2
|
+
export default async function toFill(page, cssSelector, text, opts) {
|
|
3
|
+
try {
|
|
4
|
+
await page.waitForSelector(cssSelector, opts);
|
|
5
|
+
// unless the user opts out, clear the input
|
|
6
|
+
// before typing into it, since most of the
|
|
7
|
+
// time this is what people will expect to
|
|
8
|
+
// happen.
|
|
9
|
+
if (!opts?.bypassInputValueReset) {
|
|
10
|
+
await page.focus(cssSelector);
|
|
11
|
+
await page.keyboard.down(metaOrControlKey());
|
|
12
|
+
await page.keyboard.press('A');
|
|
13
|
+
await page.keyboard.up(metaOrControlKey());
|
|
14
|
+
await page.keyboard.press('Backspace');
|
|
12
15
|
}
|
|
16
|
+
await page.type(cssSelector, text);
|
|
13
17
|
return {
|
|
14
18
|
pass: true,
|
|
15
|
-
|
|
19
|
+
message: () => {
|
|
20
|
+
throw new Error('cannot negate toFill');
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return {
|
|
26
|
+
pass: false,
|
|
27
|
+
message: () => `failed to fill input matching selector ${cssSelector} with text "text"`,
|
|
16
28
|
};
|
|
17
|
-
}
|
|
18
|
-
successText: () => `Expected page to have clickable link with text: "${text}"`,
|
|
19
|
-
failureText: () => `Expected page not to have clickable link with text: "${text}"`,
|
|
20
|
-
});
|
|
29
|
+
}
|
|
21
30
|
}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export default async function toHaveChecked(page, expectedText) {
|
|
5
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
6
|
-
requirePuppeteerPage(page);
|
|
7
|
-
const checkbox = await page.$(`input[type="checkbox"][value="${expectedText}"]`);
|
|
8
|
-
if (!checkbox)
|
|
9
|
-
return evaluationFailure(`A checkbox was not found with "${expectedText}"`);
|
|
1
|
+
export default async function toHaveChecked(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const checkbox = await page.waitForSelector(`input[type="checkbox"][value="${expectedText}"]`, opts);
|
|
10
4
|
const isChecked = await page.evaluate(checkbox => checkbox.checked, checkbox);
|
|
11
5
|
return {
|
|
12
6
|
pass: isChecked,
|
|
13
|
-
|
|
7
|
+
message: () => {
|
|
8
|
+
throw new Error('cannot negate toHaveChecked, try toHaveUnchecked');
|
|
9
|
+
},
|
|
14
10
|
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return {
|
|
14
|
+
pass: false,
|
|
15
|
+
message: () => `Expected page to have checked checkbox with text: "${expectedText}"`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
19
18
|
}
|
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import requirePuppeteerPage from '../internal/requirePuppeteerPage.js';
|
|
5
|
-
export default async function toHaveLink(page, expectedText) {
|
|
6
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
7
|
-
requirePuppeteerPage(page);
|
|
8
|
-
let el = undefined;
|
|
9
|
-
try {
|
|
10
|
-
el = await page.locator(`a ::-p-text(${expectedText})`).setTimeout(10).wait();
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
if (err instanceof TimeoutError)
|
|
14
|
-
return evaluationFailure(expectedText);
|
|
15
|
-
throw err;
|
|
16
|
-
}
|
|
1
|
+
export default async function toHaveLink(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
await page.waitForSelector(`a ::-p-text(${expectedText})`, opts);
|
|
17
4
|
return {
|
|
18
|
-
pass:
|
|
19
|
-
|
|
5
|
+
pass: true,
|
|
6
|
+
message: () => {
|
|
7
|
+
throw new Error('cannot negate toFill');
|
|
8
|
+
},
|
|
20
9
|
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return {
|
|
13
|
+
pass: false,
|
|
14
|
+
message: () => `Expected page not to have checked checkbox with text: "${expectedText}"`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
25
17
|
}
|
|
@@ -9,7 +9,9 @@ export default async function toHavePath(page, expectedPath) {
|
|
|
9
9
|
actual: expectedPath,
|
|
10
10
|
};
|
|
11
11
|
}, {
|
|
12
|
-
successText: () =>
|
|
12
|
+
successText: () => {
|
|
13
|
+
throw new Error('cannot negate toHavePath');
|
|
14
|
+
},
|
|
13
15
|
failureText: () => `Expected page not to have path: "${expectedPath}"`,
|
|
14
16
|
});
|
|
15
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export default async function toHaveSelector(page, selector) {
|
|
1
|
+
export default async function toHaveSelector(page, selector, opts) {
|
|
2
2
|
try {
|
|
3
|
-
await page.waitForSelector(selector);
|
|
3
|
+
await page.waitForSelector(selector, opts);
|
|
4
4
|
return {
|
|
5
5
|
pass: true,
|
|
6
6
|
message: () => {
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export default async function toHaveUnchecked(page, expectedText) {
|
|
5
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
6
|
-
requirePuppeteerPage(page);
|
|
7
|
-
const checkbox = await page.$(`input[type="checkbox"][value="${expectedText}"]`);
|
|
8
|
-
if (!checkbox)
|
|
9
|
-
return evaluationFailure(`A checkbox was not found with "${expectedText}"`);
|
|
1
|
+
export default async function toHaveUnchecked(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const checkbox = await page.waitForSelector(`input[type="checkbox"][value="${expectedText}"]`, opts);
|
|
10
4
|
const isChecked = await page.evaluate(checkbox => checkbox.checked, checkbox);
|
|
11
5
|
return {
|
|
12
6
|
pass: !isChecked,
|
|
13
|
-
|
|
7
|
+
message: () => {
|
|
8
|
+
throw new Error('cannot negate toHaveUnchecked, try toHaveChecked');
|
|
9
|
+
},
|
|
14
10
|
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return {
|
|
14
|
+
pass: false,
|
|
15
|
+
message: () => `Expected page not to have checked checkbox with text: "${expectedText}"`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
19
18
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return await evaluateWithRetryAndTimeout(page, async () => {
|
|
5
|
-
requirePuppeteerPage(page);
|
|
1
|
+
export default async function toNotHaveSelector(page, selector, opts) {
|
|
2
|
+
try {
|
|
3
|
+
await page.waitForSelector(selector, { hidden: true, ...opts });
|
|
6
4
|
return {
|
|
7
|
-
pass:
|
|
8
|
-
|
|
5
|
+
pass: true,
|
|
6
|
+
message: () => {
|
|
7
|
+
throw new Error('Cannot negate toNotHaveSelector, use toHaveSelector instead');
|
|
8
|
+
},
|
|
9
9
|
};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return {
|
|
13
|
+
pass: false,
|
|
14
|
+
message: () => `Expected page to not have visible selector, but it did: ${selector}`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
16
17
|
}
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
requirePuppeteerPage(page);
|
|
7
|
-
const checkbox = await page.$(`input[type="checkbox"][value="${expectedText}"]`);
|
|
8
|
-
if (!checkbox)
|
|
9
|
-
return evaluationFailure(`A checkbox was not found with "${expectedText}"`);
|
|
10
|
-
const isChecked = await page.evaluate(checkbox => checkbox.checked, checkbox);
|
|
1
|
+
export default async function toUncheck(page, expectedText, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const el = await page.waitForSelector(`label::-p-text(${expectedText}`, opts);
|
|
4
|
+
await el.click();
|
|
5
|
+
const isChecked = await page.evaluate(checkbox => checkbox.checked, el);
|
|
11
6
|
if (!isChecked)
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
return {
|
|
8
|
+
pass: false,
|
|
9
|
+
message: () => `A checkbox was found with "${expectedText}", but it is already unchecked`,
|
|
10
|
+
};
|
|
11
|
+
await el.click();
|
|
12
|
+
const isUncheckedNow = await page.evaluate(checkbox => checkbox.checked, el);
|
|
15
13
|
return {
|
|
16
|
-
pass:
|
|
17
|
-
|
|
14
|
+
pass: isUncheckedNow,
|
|
15
|
+
message: () => {
|
|
16
|
+
throw new Error('Cannot negate toUncheck, try toCheck');
|
|
17
|
+
},
|
|
18
18
|
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return {
|
|
22
|
+
pass: false,
|
|
23
|
+
message: `Expected page to have checkable element with text: "${expectedText}"`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
23
26
|
}
|
package/dist/esm/src/index.js
CHANGED
|
@@ -7,6 +7,6 @@ export { SpecSession } from './unit/SpecSession.js';
|
|
|
7
7
|
export { default as providePuppeteerViteMatchers } from './feature/helpers/providePuppeteerViteMatchers.js';
|
|
8
8
|
export { default as launchBrowser } from './feature/helpers/launchBrowser.js';
|
|
9
9
|
export { default as launchPage } from './feature/helpers/launchPage.js';
|
|
10
|
-
export { default as
|
|
10
|
+
export { default as launchDevServer, stopDevServers, stopDevServer, } from './feature/helpers/launchDevServer.js';
|
|
11
11
|
export { default as visit } from './feature/helpers/visit.js';
|
|
12
12
|
export default {};
|