@rvoh/psychic-spec-helpers 3.3.0 → 3.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.
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import applyDefaultWaitForOpts from '../helpers/applyDefaultWaitForOpts.js';
|
|
2
2
|
export default async function toHaveSelector(page, selector, opts) {
|
|
3
|
+
// Presence-only contract: this matcher asserts that the selector is
|
|
4
|
+
// attached to the DOM, regardless of visibility. Strip visible/hidden so
|
|
5
|
+
// a caller-passed { visible: true } can't narrow the check to also
|
|
6
|
+
// require visibility.
|
|
7
|
+
const waitForOpts = applyDefaultWaitForOpts(opts);
|
|
8
|
+
delete waitForOpts.visible;
|
|
9
|
+
delete waitForOpts.hidden;
|
|
3
10
|
try {
|
|
4
|
-
await page.waitForSelector(selector,
|
|
11
|
+
await page.waitForSelector(selector, waitForOpts);
|
|
5
12
|
return {
|
|
6
13
|
pass: true,
|
|
7
14
|
message: () => {
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
import applyDefaultWaitForOpts from '../helpers/applyDefaultWaitForOpts.js';
|
|
2
|
+
import sleep from '../../shared/sleep.js';
|
|
2
3
|
export default async function toNotHaveSelector(page, selector, opts) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
// Presence-only contract: this matcher asserts that the selector is
|
|
5
|
+
// absent from the DOM, regardless of visibility. A present-but-hidden
|
|
6
|
+
// element must FAIL this matcher, so we poll for true DOM absence via
|
|
7
|
+
// page.$ (rather than relying on waitForSelector({ hidden: true }),
|
|
8
|
+
// which only asserts invisibility). page.$ (not document.querySelector)
|
|
9
|
+
// is used so Puppeteer's extended selectors like ::-p-text keep working.
|
|
10
|
+
const timeout = applyDefaultWaitForOpts(opts).timeout ?? 5000;
|
|
11
|
+
const interval = 50;
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
async function poll() {
|
|
14
|
+
const element = await page.$(selector);
|
|
15
|
+
if (!element) {
|
|
16
|
+
return {
|
|
17
|
+
pass: true,
|
|
18
|
+
message: () => {
|
|
19
|
+
throw new Error('Cannot negate toNotHaveSelector, use toHaveSelector instead');
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (Date.now() >= startTime + timeout) {
|
|
24
|
+
await element.dispose();
|
|
25
|
+
return {
|
|
26
|
+
pass: false,
|
|
27
|
+
message: () => `Expected page to not have selector, but it did: ${selector}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
await element.dispose();
|
|
31
|
+
await sleep(interval);
|
|
32
|
+
return await poll();
|
|
17
33
|
}
|
|
34
|
+
return await poll();
|
|
18
35
|
}
|
package/package.json
CHANGED
|
@@ -6,8 +6,16 @@ export default async function toHaveSelector(
|
|
|
6
6
|
selector: string,
|
|
7
7
|
opts?: WaitForSelectorOptions
|
|
8
8
|
) {
|
|
9
|
+
// Presence-only contract: this matcher asserts that the selector is
|
|
10
|
+
// attached to the DOM, regardless of visibility. Strip visible/hidden so
|
|
11
|
+
// a caller-passed { visible: true } can't narrow the check to also
|
|
12
|
+
// require visibility.
|
|
13
|
+
const waitForOpts = applyDefaultWaitForOpts(opts)
|
|
14
|
+
delete waitForOpts.visible
|
|
15
|
+
delete waitForOpts.hidden
|
|
16
|
+
|
|
9
17
|
try {
|
|
10
|
-
await page.waitForSelector(selector,
|
|
18
|
+
await page.waitForSelector(selector, waitForOpts)
|
|
11
19
|
return {
|
|
12
20
|
pass: true,
|
|
13
21
|
message: () => {
|
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
import { Page, WaitForSelectorOptions } from 'puppeteer'
|
|
2
2
|
import applyDefaultWaitForOpts from '../helpers/applyDefaultWaitForOpts.js'
|
|
3
|
+
import sleep from '../../shared/sleep.js'
|
|
3
4
|
|
|
4
5
|
export default async function toNotHaveSelector(
|
|
5
6
|
page: Page,
|
|
6
7
|
selector: string,
|
|
7
8
|
opts?: WaitForSelectorOptions
|
|
8
9
|
) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
// Presence-only contract: this matcher asserts that the selector is
|
|
11
|
+
// absent from the DOM, regardless of visibility. A present-but-hidden
|
|
12
|
+
// element must FAIL this matcher, so we poll for true DOM absence via
|
|
13
|
+
// page.$ (rather than relying on waitForSelector({ hidden: true }),
|
|
14
|
+
// which only asserts invisibility). page.$ (not document.querySelector)
|
|
15
|
+
// is used so Puppeteer's extended selectors like ::-p-text keep working.
|
|
16
|
+
const timeout = applyDefaultWaitForOpts(opts).timeout ?? 5000
|
|
17
|
+
const interval = 50
|
|
18
|
+
const startTime = Date.now()
|
|
19
|
+
|
|
20
|
+
async function poll(): Promise<{ pass: boolean; message: () => string }> {
|
|
21
|
+
const element = await page.$(selector)
|
|
22
|
+
if (!element) {
|
|
23
|
+
return {
|
|
24
|
+
pass: true,
|
|
25
|
+
message: () => {
|
|
26
|
+
throw new Error('Cannot negate toNotHaveSelector, use toHaveSelector instead')
|
|
27
|
+
},
|
|
28
|
+
}
|
|
16
29
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
|
|
31
|
+
if (Date.now() >= startTime + timeout) {
|
|
32
|
+
await element.dispose()
|
|
33
|
+
return {
|
|
34
|
+
pass: false,
|
|
35
|
+
message: () => `Expected page to not have selector, but it did: ${selector}`,
|
|
36
|
+
}
|
|
21
37
|
}
|
|
38
|
+
|
|
39
|
+
await element.dispose()
|
|
40
|
+
await sleep(interval)
|
|
41
|
+
return await poll()
|
|
22
42
|
}
|
|
43
|
+
|
|
44
|
+
return await poll()
|
|
23
45
|
}
|