@rvoh/psychic-spec-helpers 0.3.1-fgbeta-8 → 0.3.1

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.
Files changed (54) hide show
  1. package/dist/esm/src/feature/helpers/metaOrControlKey.js +4 -0
  2. package/dist/esm/src/feature/helpers/providePuppeteerViteMatchers.js +26 -26
  3. package/dist/esm/src/feature/helpers/visit.js +0 -1
  4. package/dist/esm/src/feature/matchers/toCheck.js +15 -20
  5. package/dist/esm/src/feature/matchers/toClick.js +14 -21
  6. package/dist/esm/src/feature/matchers/toClickButton.js +14 -21
  7. package/dist/esm/src/feature/matchers/toClickLink.js +14 -21
  8. package/dist/esm/src/feature/matchers/toClickSelector.js +14 -21
  9. package/dist/esm/src/feature/matchers/toFill.js +25 -16
  10. package/dist/esm/src/feature/matchers/toHaveChecked.js +13 -14
  11. package/dist/esm/src/feature/matchers/toHaveLink.js +14 -22
  12. package/dist/esm/src/feature/matchers/toHavePath.js +3 -1
  13. package/dist/esm/src/feature/matchers/toHaveSelector.js +5 -6
  14. package/dist/esm/src/feature/matchers/toHaveUnchecked.js +13 -14
  15. package/dist/esm/src/feature/matchers/toMatchTextContent.js +3 -6
  16. package/dist/esm/src/feature/matchers/toNotHaveSelector.js +14 -11
  17. package/dist/esm/src/feature/matchers/toNotMatchTextContent.js +3 -1
  18. package/dist/esm/src/feature/matchers/toUncheck.js +22 -19
  19. package/dist/types/src/feature/helpers/metaOrControlKey.d.ts +1 -0
  20. package/dist/types/src/feature/helpers/visit.d.ts +1 -1
  21. package/dist/types/src/feature/matchers/toCheck.d.ts +6 -3
  22. package/dist/types/src/feature/matchers/toClick.d.ts +6 -3
  23. package/dist/types/src/feature/matchers/toClickButton.d.ts +6 -3
  24. package/dist/types/src/feature/matchers/toClickLink.d.ts +6 -3
  25. package/dist/types/src/feature/matchers/toClickSelector.d.ts +6 -3
  26. package/dist/types/src/feature/matchers/toFill.d.ts +6 -3
  27. package/dist/types/src/feature/matchers/toHaveChecked.d.ts +6 -3
  28. package/dist/types/src/feature/matchers/toHaveLink.d.ts +3 -3
  29. package/dist/types/src/feature/matchers/toHaveSelector.d.ts +2 -2
  30. package/dist/types/src/feature/matchers/toHaveUnchecked.d.ts +3 -3
  31. package/dist/types/src/feature/matchers/toMatchTextContent.d.ts +2 -2
  32. package/dist/types/src/feature/matchers/toNotHaveSelector.d.ts +3 -3
  33. package/dist/types/src/feature/matchers/toUncheck.d.ts +8 -2
  34. package/dist/types/src/index.d.ts +14 -13
  35. package/package.json +1 -2
  36. package/src/feature/helpers/metaOrControlKey.ts +4 -0
  37. package/src/feature/helpers/providePuppeteerViteMatchers.ts +32 -28
  38. package/src/feature/helpers/visit.ts +0 -1
  39. package/src/feature/matchers/toCheck.ts +20 -30
  40. package/src/feature/matchers/toClick.ts +20 -25
  41. package/src/feature/matchers/toClickButton.ts +20 -25
  42. package/src/feature/matchers/toClickLink.ts +20 -25
  43. package/src/feature/matchers/toClickSelector.ts +20 -25
  44. package/src/feature/matchers/toFill.ts +36 -23
  45. package/src/feature/matchers/toHaveChecked.ts +23 -22
  46. package/src/feature/matchers/toHaveLink.ts +19 -27
  47. package/src/feature/matchers/toHavePath.ts +3 -1
  48. package/src/feature/matchers/toHaveSelector.ts +10 -7
  49. package/src/feature/matchers/toHaveUnchecked.ts +23 -22
  50. package/src/feature/matchers/toMatchTextContent.ts +5 -8
  51. package/src/feature/matchers/toNotHaveSelector.ts +19 -18
  52. package/src/feature/matchers/toNotMatchTextContent.ts +3 -1
  53. package/src/feature/matchers/toUncheck.ts +28 -29
  54. package/src/index.ts +14 -13
@@ -1,5 +1,8 @@
1
- import { Page } from 'puppeteer';
2
- export default function toClickLink(page: Page, expectedText: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toClickLink(page: Page, expectedText: string, opts?: WaitForSelectorOptions): Promise<{
4
3
  pass: boolean;
4
+ message: () => never;
5
+ } | {
6
+ pass: boolean;
7
+ message: string;
5
8
  }>;
@@ -1,5 +1,8 @@
1
- import { Page } from 'puppeteer';
2
- export default function toClickSelector(page: Page, cssSelector: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toClickSelector(page: Page, cssSelector: string, opts?: WaitForSelectorOptions): Promise<{
4
3
  pass: boolean;
4
+ message: () => never;
5
+ } | {
6
+ pass: boolean;
7
+ message: string;
5
8
  }>;
@@ -1,5 +1,8 @@
1
- import { Page } from 'puppeteer';
2
- export default function toFill(page: Page, cssSelector: string, text: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toFill(page: Page, cssSelector: string, text: string, opts?: ToFillMatcherOpts): Promise<{
4
3
  pass: boolean;
4
+ message: () => string;
5
5
  }>;
6
+ export type ToFillMatcherOpts = WaitForSelectorOptions & {
7
+ bypassInputValueReset: boolean;
8
+ };
@@ -1,5 +1,8 @@
1
- import { Page } from 'puppeteer';
2
- export default function toHaveChecked(page: Page, expectedText: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toHaveChecked(page: Page, expectedText: string, opts?: WaitForSelectorOptions): Promise<{
3
+ pass: any;
4
+ message: () => never;
5
+ } | {
4
6
  pass: boolean;
7
+ message: () => string;
5
8
  }>;
@@ -1,5 +1,5 @@
1
- import { Page } from 'puppeteer';
2
- export default function toHaveLink(page: Page, expectedText: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toHaveLink(page: Page, expectedText: string, opts?: WaitForSelectorOptions): Promise<{
4
3
  pass: boolean;
4
+ message: () => string;
5
5
  }>;
@@ -1,5 +1,5 @@
1
- import { Page } from 'puppeteer';
2
- export default function toHaveSelector(page: Page, selector: string): Promise<{
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toHaveSelector(page: Page, selector: string, opts?: WaitForSelectorOptions): Promise<{
3
3
  pass: boolean;
4
4
  message: () => string;
5
5
  }>;
@@ -1,5 +1,5 @@
1
- import { Page } from 'puppeteer';
2
- export default function toHaveUnchecked(page: Page, expectedText: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toHaveUnchecked(page: Page, expectedText: string, opts?: WaitForSelectorOptions): Promise<{
4
3
  pass: boolean;
4
+ message: () => string;
5
5
  }>;
@@ -1,7 +1,7 @@
1
- import { Page } from 'puppeteer';
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
2
  export default function toMatchTextContent(page: Page, text: string, { selector }?: {
3
3
  selector?: string;
4
- }): Promise<{
4
+ } & WaitForSelectorOptions): Promise<{
5
5
  pass: boolean;
6
6
  message: () => string;
7
7
  }>;
@@ -1,5 +1,5 @@
1
- import { Page } from 'puppeteer';
2
- export default function toNotHaveSelector(page: Page, expectedSelector: string): Promise<{
3
- message: () => string;
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toNotHaveSelector(page: Page, selector: string, opts?: WaitForSelectorOptions): Promise<{
4
3
  pass: boolean;
4
+ message: () => string;
5
5
  }>;
@@ -1,5 +1,11 @@
1
- import { Page } from 'puppeteer';
2
- export default function toUncheck(page: Page, expectedText: string): Promise<{
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
2
+ export default function toUncheck(page: Page, expectedText: string, opts?: WaitForSelectorOptions): Promise<{
3
+ pass: boolean;
3
4
  message: () => string;
5
+ } | {
6
+ pass: any;
7
+ message: () => never;
8
+ } | {
4
9
  pass: boolean;
10
+ message: string;
5
11
  }>;
@@ -1,6 +1,7 @@
1
1
  import { ExpectToEvaluateOpts } from './feature/internal/evaluateWithRetryAndTimeout.js';
2
2
  import { CustomMatcherResult } from './feature/helpers/providePuppeteerViteMatchers.js';
3
- import { Page } from 'puppeteer';
3
+ import { Page, WaitForSelectorOptions } from 'puppeteer';
4
+ import { ToFillMatcherOpts } from './feature/matchers/toFill.js';
4
5
  export { default as specRequest } from './unit/SpecRequest.js';
5
6
  export { default as createPsychicServer } from './unit/createPsychicServer.js';
6
7
  export { SpecRequest } from './unit/SpecRequest.js';
@@ -27,20 +28,20 @@ interface PuppeteerAssertions {
27
28
  toEqualCalendarDate(expected: any): CustomMatcherResult;
28
29
  toMatchTextContent(expected: any): Promise<CustomMatcherResult>;
29
30
  toNotMatchTextContent(expected: any): Promise<CustomMatcherResult>;
30
- toHaveSelector(expected: any): Promise<CustomMatcherResult>;
31
- toNotHaveSelector(expected: any): Promise<CustomMatcherResult>;
32
- toCheck(expected: any): Promise<CustomMatcherResult>;
33
- toClick(expected: any): Promise<CustomMatcherResult>;
34
- toClickLink(expected: any): Promise<CustomMatcherResult>;
35
- toClickButton(expected: any): Promise<CustomMatcherResult>;
36
- toClickSelector(expected: any): Promise<CustomMatcherResult>;
31
+ toHaveSelector(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
32
+ toNotHaveSelector(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
33
+ toCheck(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
34
+ toClick(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
35
+ toClickLink(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
36
+ toClickButton(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
37
+ toClickSelector(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
37
38
  toHavePath(expected: any): Promise<CustomMatcherResult>;
38
39
  toHaveUrl(expected: any): Promise<CustomMatcherResult>;
39
- toHaveChecked(expected: any): Promise<CustomMatcherResult>;
40
- toHaveUnchecked(expected: any): Promise<CustomMatcherResult>;
41
- toHaveLink(expected: any): Promise<CustomMatcherResult>;
42
- toFill(cssSelector: string, text: string): Promise<CustomMatcherResult>;
43
- toUncheck(expected: any): Promise<CustomMatcherResult>;
40
+ toHaveChecked(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
41
+ toHaveUnchecked(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
42
+ toHaveLink(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
43
+ toFill(cssSelector: string, text: string, opts?: ToFillMatcherOpts): Promise<CustomMatcherResult>;
44
+ toUncheck(expected: any, opts?: WaitForSelectorOptions): Promise<CustomMatcherResult>;
44
45
  toEvaluate(expected: (a: any) => boolean | Promise<boolean>, opts: ExpectToEvaluateOpts): Promise<CustomMatcherResult>;
45
46
  }
46
47
  declare const _default: {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@rvoh/psychic-spec-helpers",
4
- "version": "0.3.1-fgbeta-8",
4
+ "version": "0.3.1",
5
5
  "description": "psychic framework spec helpers",
6
6
  "main": "./dist/cjs/src/index.js",
7
7
  "module": "./dist/esm/src/index.js",
@@ -19,7 +19,6 @@
19
19
  "dist/**/*"
20
20
  ],
21
21
  "scripts": {
22
- "publish": "yarn npm publish --access public",
23
22
  "build": "echo \"building psychic-spec-helpers...\" && rm -rf dist && npx tsc -p ./tsconfig.json",
24
23
  "prepack": "yarn build"
25
24
  },
@@ -0,0 +1,4 @@
1
+ export default function metaOrControlKey(): 'Meta' | 'Control' {
2
+ // Use 'Meta' for macOS and 'Control' for Windows/Linux
3
+ return process.platform === 'darwin' ? 'Meta' : 'Control'
4
+ }
@@ -1,4 +1,4 @@
1
- import { Page } from 'puppeteer'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
2
2
  import evaluateWithRetryAndTimeout, {
3
3
  ExpectToEvaluateOpts,
4
4
  ExpectToEvaluateReturnType,
@@ -18,44 +18,48 @@ import toHaveUrl from '../matchers/toHaveUrl.js'
18
18
  import toHaveLink from '../matchers/toHaveLink.js'
19
19
  import toHaveChecked from '../matchers/toHaveChecked.js'
20
20
  import toHaveUnchecked from '../matchers/toHaveUnchecked.js'
21
- import toFill from '../matchers/toFill.js'
21
+ import toFill, { ToFillMatcherOpts } from '../matchers/toFill.js'
22
22
 
23
23
  export default function providePuppeteerViteMatchers() {
24
24
  ;((global as any).expect as any).extend({
25
- async toMatchTextContent(page: Page, text: string) {
26
- return await toMatchTextContent(page, text)
25
+ async toMatchTextContent(
26
+ page: Page,
27
+ text: string,
28
+ opts?: { selector?: string } & WaitForSelectorOptions
29
+ ) {
30
+ return await toMatchTextContent(page, text, opts)
27
31
  },
28
32
 
29
33
  async toNotMatchTextContent(page: Page, text: string) {
30
34
  return await toNotMatchTextContent(page, text)
31
35
  },
32
36
 
33
- async toHaveSelector(page: Page, cssSelector: string) {
34
- return await toHaveSelector(page, cssSelector)
37
+ async toHaveSelector(page: Page, cssSelector: string, opts?: WaitForSelectorOptions) {
38
+ return await toHaveSelector(page, cssSelector, opts)
35
39
  },
36
40
 
37
- async toNotHaveSelector(page: Page, cssSelector: string) {
38
- return await toNotHaveSelector(page, cssSelector)
41
+ async toNotHaveSelector(page: Page, cssSelector: string, opts?: WaitForSelectorOptions) {
42
+ return await toNotHaveSelector(page, cssSelector, opts)
39
43
  },
40
44
 
41
- async toCheck(page: Page, text: string) {
42
- return await toCheck(page, text)
45
+ async toCheck(page: Page, text: string, opts?: WaitForSelectorOptions) {
46
+ return await toCheck(page, text, opts)
43
47
  },
44
48
 
45
- async toClick(page: Page, text: string) {
46
- return await toClick(page, text)
49
+ async toClick(page: Page, text: string, opts?: WaitForSelectorOptions) {
50
+ return await toClick(page, text, opts)
47
51
  },
48
52
 
49
- async toClickLink(page: Page, text: string) {
50
- return await toClickLink(page, text)
53
+ async toClickLink(page: Page, text: string, opts?: WaitForSelectorOptions) {
54
+ return await toClickLink(page, text, opts)
51
55
  },
52
56
 
53
- async toClickButton(page: Page, text: string) {
54
- return await toClickButton(page, text)
57
+ async toClickButton(page: Page, text: string, opts?: WaitForSelectorOptions) {
58
+ return await toClickButton(page, text, opts)
55
59
  },
56
60
 
57
- async toClickSelector(page: Page, cssSelector: string) {
58
- return await toClickSelector(page, cssSelector)
61
+ async toClickSelector(page: Page, cssSelector: string, opts?: WaitForSelectorOptions) {
62
+ return await toClickSelector(page, cssSelector, opts)
59
63
  },
60
64
 
61
65
  async toHavePath(page: Page, path: string) {
@@ -66,24 +70,24 @@ export default function providePuppeteerViteMatchers() {
66
70
  return await toHaveUrl(page, url)
67
71
  },
68
72
 
69
- async toHaveChecked(page: Page, text: string) {
70
- return await toHaveChecked(page, text)
73
+ async toHaveChecked(page: Page, text: string, opts?: WaitForSelectorOptions) {
74
+ return await toHaveChecked(page, text, opts)
71
75
  },
72
76
 
73
- async toHaveUnchecked(page: Page, checked: string) {
74
- return await toHaveUnchecked(page, checked)
77
+ async toHaveUnchecked(page: Page, checked: string, opts?: WaitForSelectorOptions) {
78
+ return await toHaveUnchecked(page, checked, opts)
75
79
  },
76
80
 
77
- async toHaveLink(page: Page, text: string) {
78
- return await toHaveLink(page, text)
81
+ async toHaveLink(page: Page, text: string, opts?: WaitForSelectorOptions) {
82
+ return await toHaveLink(page, text, opts)
79
83
  },
80
84
 
81
- async toFill(page: Page, cssSelector: string, text: string) {
82
- return await toFill(page, cssSelector, text)
85
+ async toFill(page: Page, cssSelector: string, text: string, opts?: ToFillMatcherOpts) {
86
+ return await toFill(page, cssSelector, text, opts)
83
87
  },
84
88
 
85
- async toUncheck(page: Page, text: string) {
86
- return await toUncheck(page, text)
89
+ async toUncheck(page: Page, text: string, opts?: WaitForSelectorOptions) {
90
+ return await toUncheck(page, text, opts)
87
91
  },
88
92
 
89
93
  async toEvaluate(
@@ -3,5 +3,4 @@ export default async function visit(
3
3
  { baseUrl = 'http://localhost:3000' }: { baseUrl?: string } = {}
4
4
  ) {
5
5
  await page.goto(`${baseUrl}/${path.replace(/^\//, '')}`)
6
- return page
7
6
  }
@@ -1,34 +1,24 @@
1
- import { Page } from 'puppeteer'
2
- import evaluateWithRetryAndTimeout from '../internal/evaluateWithRetryAndTimeout.js'
3
- import evaluationFailure from '../internal/evaluationFailure.js'
4
- import requirePuppeteerPage from '../internal/requirePuppeteerPage.js'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
5
2
 
6
- export default async function toCheck(page: Page, expectedText: string) {
7
- return await evaluateWithRetryAndTimeout(
8
- page,
9
- async () => {
10
- requirePuppeteerPage(page)
3
+ export default async function toCheck(
4
+ page: Page,
5
+ expectedText: string,
6
+ opts?: WaitForSelectorOptions
7
+ ) {
8
+ try {
9
+ const el = await page.waitForSelector(`label::-p-text(${expectedText}`, opts)
10
+ await el!.click()
11
11
 
12
- const checkbox = await page.$(`input[type="checkbox"][value="${expectedText}"]`)
13
- if (!checkbox) return evaluationFailure(`A checkbox was not found with "${expectedText}"`)
14
-
15
- const isChecked = await page.evaluate(checkbox => checkbox.checked, checkbox)
16
- if (isChecked)
17
- return evaluationFailure(
18
- `A checkbox was found with "${expectedText}", but it is already checked`
19
- )
20
-
21
- await checkbox.click()
22
- const isCheckedNow = await page.evaluate(checkbox => checkbox.checked, checkbox)
23
-
24
- return {
25
- pass: isCheckedNow,
26
- actual: expectedText,
27
- }
28
- },
29
- {
30
- successText: r => `Expected page to have checkable checkbox with text: "${expectedText}"`,
31
- failureText: r => `Expected page not to have checkable checkbox with text: "${expectedText}"`,
12
+ return {
13
+ pass: true,
14
+ message: () => {
15
+ throw new Error('Cannot negate toCheck')
16
+ },
17
+ }
18
+ } catch (error) {
19
+ return {
20
+ pass: false,
21
+ message: `Expected page to have checkable element with text: "${expectedText}"`,
32
22
  }
33
- )
23
+ }
34
24
  }
@@ -1,29 +1,24 @@
1
- import { Page, TimeoutError } from 'puppeteer'
2
- import evaluateWithRetryAndTimeout from '../internal/evaluateWithRetryAndTimeout.js'
3
- import evaluationFailure from '../internal/evaluationFailure.js'
4
- import requirePuppeteerPage from '../internal/requirePuppeteerPage.js'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
5
2
 
6
- export default async function toClick(page: Page, expectedText: string) {
7
- return await evaluateWithRetryAndTimeout(
8
- page,
9
- async () => {
10
- requirePuppeteerPage(page)
3
+ export default async function toClick(
4
+ page: Page,
5
+ expectedText: string,
6
+ opts?: WaitForSelectorOptions
7
+ ) {
8
+ try {
9
+ const el = await page.waitForSelector(`*::-p-text(${expectedText})`, opts)
10
+ await el!.click()
11
11
 
12
- try {
13
- ;(await page.$(`*::-p-text(${expectedText})`))!.click()
14
- } catch (err) {
15
- if (err instanceof TimeoutError) return evaluationFailure(expectedText)
16
- throw err
17
- }
18
-
19
- return {
20
- pass: true,
21
- actual: expectedText,
22
- }
23
- },
24
- {
25
- successText: () => `Expected page to have clickable element with text: "${expectedText}"`,
26
- failureText: () => `Expected page not to have clickable element with text: "${expectedText}"`,
12
+ return {
13
+ pass: true,
14
+ message: () => {
15
+ throw new Error('Cannot negate toClick')
16
+ },
17
+ }
18
+ } catch (error) {
19
+ return {
20
+ pass: false,
21
+ message: `Expected page to have clickable element with text: "${expectedText}"`,
27
22
  }
28
- )
23
+ }
29
24
  }
@@ -1,29 +1,24 @@
1
- import { Page, TimeoutError } from 'puppeteer'
2
- import evaluateWithRetryAndTimeout from '../internal/evaluateWithRetryAndTimeout.js'
3
- import evaluationFailure from '../internal/evaluationFailure.js'
4
- import requirePuppeteerPage from '../internal/requirePuppeteerPage.js'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
5
2
 
6
- export default async function toClickButton(page: Page, expectedText: string) {
7
- return await evaluateWithRetryAndTimeout(
8
- page,
9
- async () => {
10
- requirePuppeteerPage(page)
3
+ export default async function toClickButton(
4
+ page: Page,
5
+ expectedText: string,
6
+ opts?: WaitForSelectorOptions
7
+ ) {
8
+ try {
9
+ const el = await page.waitForSelector('button::-p-text(Submit)', opts)
10
+ await el!.click()
11
11
 
12
- try {
13
- ;(await page.$('button::-p-text(Submit)'))!.click()
14
- } catch (err) {
15
- if (err instanceof TimeoutError) return evaluationFailure(expectedText)
16
- throw err
17
- }
18
-
19
- return {
20
- pass: true,
21
- actual: expectedText,
22
- }
23
- },
24
- {
25
- successText: () => `Expected page to have clickable button with text: "${expectedText}"`,
26
- failureText: () => `Expected page not to have clickable button with text: "${expectedText}"`,
12
+ return {
13
+ pass: true,
14
+ message: () => {
15
+ throw new Error('Cannot negate toClickLink')
16
+ },
17
+ }
18
+ } catch (error) {
19
+ return {
20
+ pass: false,
21
+ message: `Expected page to have clickable link with matching text: "${expectedText}"`,
27
22
  }
28
- )
23
+ }
29
24
  }
@@ -1,29 +1,24 @@
1
- import { Page, TimeoutError } from 'puppeteer'
2
- import evaluateWithRetryAndTimeout from '../internal/evaluateWithRetryAndTimeout.js'
3
- import evaluationFailure from '../internal/evaluationFailure.js'
4
- import requirePuppeteerPage from '../internal/requirePuppeteerPage.js'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
5
2
 
6
- export default async function toClickLink(page: Page, expectedText: string) {
7
- return await evaluateWithRetryAndTimeout(
8
- page,
9
- async () => {
10
- requirePuppeteerPage(page)
3
+ export default async function toClickLink(
4
+ page: Page,
5
+ expectedText: string,
6
+ opts?: WaitForSelectorOptions
7
+ ) {
8
+ try {
9
+ const el = await page.waitForSelector(`a ::-p-text(${expectedText})`, opts)
10
+ await el!.click()
11
11
 
12
- try {
13
- ;(await page.$(`a ::-p-text(${expectedText})`))!.click()
14
- } catch (err) {
15
- if (err instanceof TimeoutError) return evaluationFailure(expectedText)
16
- throw err
17
- }
18
-
19
- return {
20
- pass: true,
21
- actual: expectedText,
22
- }
23
- },
24
- {
25
- successText: () => `Expected page to have clickable link with text: "${expectedText}"`,
26
- failureText: () => `Expected page not to have clickable link with text: "${expectedText}"`,
12
+ return {
13
+ pass: true,
14
+ message: () => {
15
+ throw new Error('Cannot negate toClickLink')
16
+ },
17
+ }
18
+ } catch (error) {
19
+ return {
20
+ pass: false,
21
+ message: `Expected page to have clickable link with matching text: "${expectedText}"`,
27
22
  }
28
- )
23
+ }
29
24
  }
@@ -1,29 +1,24 @@
1
- import { Page, TimeoutError } from 'puppeteer'
2
- import evaluateWithRetryAndTimeout from '../internal/evaluateWithRetryAndTimeout.js'
3
- import evaluationFailure from '../internal/evaluationFailure.js'
4
- import requirePuppeteerPage from '../internal/requirePuppeteerPage.js'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
5
2
 
6
- export default async function toClickSelector(page: Page, cssSelector: string) {
7
- return await evaluateWithRetryAndTimeout(
8
- page,
9
- async () => {
10
- requirePuppeteerPage(page)
3
+ export default async function toClickSelector(
4
+ page: Page,
5
+ cssSelector: string,
6
+ opts?: WaitForSelectorOptions
7
+ ) {
8
+ try {
9
+ const el = await page.waitForSelector(cssSelector, opts)
10
+ await el!.click()
11
11
 
12
- try {
13
- ;(await page.$(cssSelector))!.click()
14
- } catch (err) {
15
- if (err instanceof TimeoutError) return evaluationFailure(cssSelector)
16
- throw err
17
- }
18
-
19
- return {
20
- pass: true,
21
- actual: cssSelector,
22
- }
23
- },
24
- {
25
- successText: () => `Expected page to have clickable selector with text: "${cssSelector}"`,
26
- failureText: () => `Expected page not to have clickable selector with text: "${cssSelector}"`,
12
+ return {
13
+ pass: true,
14
+ message: () => {
15
+ throw new Error('Cannot negate toNotMatchTextContent, use toMatchTextContent instead')
16
+ },
17
+ }
18
+ } catch (error) {
19
+ return {
20
+ pass: false,
21
+ message: `Expected page to have clickable element with matching selector: "${cssSelector}"`,
27
22
  }
28
- )
23
+ }
29
24
  }
@@ -1,28 +1,41 @@
1
- import { Page } from 'puppeteer'
2
- import evaluateWithRetryAndTimeout from '../internal/evaluateWithRetryAndTimeout.js'
3
- import evaluationFailure from '../internal/evaluationFailure.js'
4
- import requirePuppeteerPage from '../internal/requirePuppeteerPage.js'
1
+ import { Page, WaitForSelectorOptions } from 'puppeteer'
2
+ import metaOrControlKey from '../helpers/metaOrControlKey.js'
5
3
 
6
- export default async function toFill(page: Page, cssSelector: string, text: string) {
7
- return await evaluateWithRetryAndTimeout(
8
- page,
9
- async () => {
10
- requirePuppeteerPage(page)
4
+ export default async function toFill(
5
+ page: Page,
6
+ cssSelector: string,
7
+ text: string,
8
+ opts?: ToFillMatcherOpts
9
+ ) {
10
+ try {
11
+ await page.waitForSelector(cssSelector, opts)
11
12
 
12
- try {
13
- await page.type(cssSelector, text)
14
- } catch {
15
- return evaluationFailure(text)
16
- }
13
+ // unless the user opts out, clear the input
14
+ // before typing into it, since most of the
15
+ // time this is what people will expect to
16
+ // happen.
17
+ if (!opts?.bypassInputValueReset) {
18
+ await page.focus(cssSelector)
19
+ await page.keyboard.down(metaOrControlKey())
20
+ await page.keyboard.press('A')
21
+ await page.keyboard.up(metaOrControlKey())
22
+ await page.keyboard.press('Backspace')
23
+ }
24
+
25
+ await page.type(cssSelector, text)
17
26
 
18
- return {
19
- pass: true,
20
- actual: text,
21
- }
22
- },
23
- {
24
- successText: () => `Expected page to have clickable link with text: "${text}"`,
25
- failureText: () => `Expected page not to have clickable link with text: "${text}"`,
27
+ return {
28
+ pass: true,
29
+ message: () => {
30
+ throw new Error('cannot negate toFill')
31
+ },
26
32
  }
27
- )
33
+ } catch {
34
+ return {
35
+ pass: false,
36
+ message: () => `failed to fill input matching selector ${cssSelector} with text "text"`,
37
+ }
38
+ }
28
39
  }
40
+
41
+ export type ToFillMatcherOpts = WaitForSelectorOptions & { bypassInputValueReset: boolean }