codeceptjs 3.4.1 → 3.5.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +9 -7
  3. package/bin/codecept.js +1 -1
  4. package/docs/ai.md +246 -0
  5. package/docs/build/Appium.js +47 -7
  6. package/docs/build/JSONResponse.js +4 -4
  7. package/docs/build/Nightmare.js +3 -1
  8. package/docs/build/OpenAI.js +122 -0
  9. package/docs/build/Playwright.js +193 -45
  10. package/docs/build/Protractor.js +3 -1
  11. package/docs/build/Puppeteer.js +45 -12
  12. package/docs/build/REST.js +15 -5
  13. package/docs/build/TestCafe.js +3 -1
  14. package/docs/build/WebDriver.js +30 -5
  15. package/docs/changelog.md +65 -0
  16. package/docs/helpers/Appium.md +152 -147
  17. package/docs/helpers/JSONResponse.md +4 -4
  18. package/docs/helpers/Nightmare.md +2 -0
  19. package/docs/helpers/OpenAI.md +70 -0
  20. package/docs/helpers/Playwright.md +194 -152
  21. package/docs/helpers/Puppeteer.md +6 -0
  22. package/docs/helpers/REST.md +6 -5
  23. package/docs/helpers/TestCafe.md +2 -0
  24. package/docs/helpers/WebDriver.md +10 -4
  25. package/docs/mobile.md +49 -2
  26. package/docs/parallel.md +56 -0
  27. package/docs/plugins.md +87 -33
  28. package/docs/secrets.md +6 -0
  29. package/docs/tutorial.md +2 -2
  30. package/docs/webapi/appendField.mustache +2 -0
  31. package/docs/webapi/type.mustache +3 -0
  32. package/lib/ai.js +171 -0
  33. package/lib/cli.js +1 -1
  34. package/lib/codecept.js +4 -0
  35. package/lib/command/dryRun.js +9 -1
  36. package/lib/command/generate.js +46 -3
  37. package/lib/command/init.js +13 -1
  38. package/lib/command/interactive.js +15 -1
  39. package/lib/command/run-workers.js +2 -1
  40. package/lib/container.js +13 -3
  41. package/lib/helper/Appium.js +45 -7
  42. package/lib/helper/JSONResponse.js +4 -4
  43. package/lib/helper/Nightmare.js +1 -1
  44. package/lib/helper/OpenAI.js +122 -0
  45. package/lib/helper/Playwright.js +190 -38
  46. package/lib/helper/Protractor.js +1 -1
  47. package/lib/helper/Puppeteer.js +40 -12
  48. package/lib/helper/REST.js +15 -5
  49. package/lib/helper/TestCafe.js +1 -1
  50. package/lib/helper/WebDriver.js +25 -5
  51. package/lib/helper/scripts/highlightElement.js +20 -0
  52. package/lib/html.js +258 -0
  53. package/lib/listener/retry.js +2 -1
  54. package/lib/pause.js +73 -17
  55. package/lib/plugin/debugErrors.js +67 -0
  56. package/lib/plugin/fakerTransform.js +4 -6
  57. package/lib/plugin/heal.js +179 -0
  58. package/lib/plugin/screenshotOnFail.js +11 -2
  59. package/lib/recorder.js +4 -4
  60. package/lib/secret.js +5 -4
  61. package/lib/step.js +6 -1
  62. package/lib/ui.js +4 -3
  63. package/lib/utils.js +4 -0
  64. package/lib/workers.js +57 -9
  65. package/package.json +25 -13
  66. package/translations/ja-JP.js +9 -9
  67. package/typings/index.d.ts +43 -9
  68. package/typings/promiseBasedTypes.d.ts +124 -24
  69. package/typings/types.d.ts +138 -30
@@ -12,26 +12,26 @@ declare namespace CodeceptJS {
12
12
 
13
13
  type Cookie = {
14
14
  name: string;
15
- value: string;
15
+ value: string | boolean;
16
16
  domain?: string,
17
17
  path?: string,
18
18
  };
19
19
 
20
20
  type RetryConfig = {
21
21
  /** Filter tests by string or regexp pattern */
22
- grep: string | RegExp;
22
+ grep?: string | RegExp;
23
23
  /** Number of times to repeat scenarios of a Feature */
24
- Feature: number;
24
+ Feature?: number;
25
25
  /** Number of times to repeat scenarios */
26
- Scenario: number;
26
+ Scenario?: number;
27
27
  /** Number of times to repeat Before hook */
28
- Before: number;
28
+ Before?: number;
29
29
  /** Number of times to repeat After hook */
30
- After: number;
30
+ After?: number;
31
31
  /** Number of times to repeat BeforeSuite hook */
32
- BeforeSuite: number;
32
+ BeforeSuite?: number;
33
33
  /** Number of times to repeat AfterSuite hook */
34
- AfterSuite: number;
34
+ AfterSuite?: number;
35
35
  };
36
36
 
37
37
  type TimeoutConfig = {
@@ -67,6 +67,14 @@ declare namespace CodeceptJS {
67
67
  * ```
68
68
  */
69
69
  output: string;
70
+ /**
71
+ * empty output folder for next run
72
+ *
73
+ * ```js
74
+ * emptyOutputFolder: true
75
+ * ```
76
+ */
77
+ emptyOutputFolder?: boolean;
70
78
  /**
71
79
  * Pattern to filter tests by name.
72
80
  * This option is useful if you plan to use multiple configs for different environments.
@@ -341,6 +349,29 @@ declare namespace CodeceptJS {
341
349
  steps: string | Array<string>
342
350
  };
343
351
 
352
+ /**
353
+ * [AI](https://codecept.io/ai/) features configuration.
354
+ */
355
+ ai?: {
356
+ /** OpenAI model to use */
357
+ model?: string,
358
+ /** temperature, measure of randomness. Lower is better. */
359
+ temperature?: number,
360
+ /** configuration for processing HTML for GPT */
361
+ html?: {
362
+ /** max size of HTML to be sent to OpenAI to avoid token limit */
363
+ maxLength?: number,
364
+ /** should HTML be changed by removing non-interactive elements */
365
+ simplify?: boolean,
366
+ /** should HTML be minified before sending */
367
+ minify?: boolean,
368
+ interactiveElements?: Array<string>,
369
+ textElements?: Array<string>,
370
+ allowedAttrs?: Array<string>,
371
+ allowedRoles?: Array<string>,
372
+ }
373
+ },
374
+
344
375
  /**
345
376
  * Enable full promise-based helper methods for [TypeScript](https://codecept.io/typescript/) project.
346
377
  * If true, all helper methods are typed as asynchronous;
@@ -392,7 +423,7 @@ declare namespace CodeceptJS {
392
423
  | { ios: string }
393
424
  | { android: string; ios: string }
394
425
  | { react: string }
395
- | { shadow: string }
426
+ | { shadow: string[] }
396
427
  | { custom: string };
397
428
 
398
429
  interface CustomLocators {}
@@ -489,6 +520,9 @@ declare const Background: CodeceptJS.IHook;
489
520
  declare const Before: CodeceptJS.IHook;
490
521
  declare const After: CodeceptJS.IHook;
491
522
 
523
+ // Plugins
524
+ declare const __: any
525
+
492
526
  interface Window {
493
527
  codeceptjs: typeof CodeceptJS.browserCodecept;
494
528
  resq: any;
@@ -756,6 +756,8 @@ declare namespace CodeceptJS {
756
756
  *
757
757
  * ```js
758
758
  * I.appendField('#myTextField', 'appended');
759
+ * // typing secret
760
+ * I.appendField('password', secret('123456'));
759
761
  * ```
760
762
  * @param field - located by label|name|CSS|XPath|strict locator
761
763
  * @param value - text value to append.
@@ -1655,16 +1657,16 @@ declare namespace CodeceptJS {
1655
1657
  *
1656
1658
  * I.seeResponseMatchesJsonSchema(joi => {
1657
1659
  * return joi.object({
1658
- * name: joi.string();
1659
- * id: joi.number();
1660
+ * name: joi.string(),
1661
+ * id: joi.number()
1660
1662
  * })
1661
1663
  * });
1662
1664
  *
1663
1665
  * // or pass a valid schema
1664
- * const joi = require('joi);
1666
+ * const joi = require('joi');
1665
1667
  *
1666
1668
  * I.seeResponseMatchesJsonSchema(joi.object({
1667
- * name: joi.string();
1669
+ * name: joi.string(),
1668
1670
  * id: joi.number();
1669
1671
  * });
1670
1672
  * ```
@@ -2167,6 +2169,8 @@ declare namespace CodeceptJS {
2167
2169
  *
2168
2170
  * ```js
2169
2171
  * I.appendField('#myTextField', 'appended');
2172
+ * // typing secret
2173
+ * I.appendField('password', secret('123456'));
2170
2174
  * ```
2171
2175
  * @param field - located by label|name|CSS|XPath|strict locator
2172
2176
  * @param value - text value to append.
@@ -2671,6 +2675,46 @@ declare namespace CodeceptJS {
2671
2675
  */
2672
2676
  grabPageScrollPosition(): Promise<PageScrollPosition>;
2673
2677
  }
2678
+ /**
2679
+ * OpenAI Helper for CodeceptJS.
2680
+ *
2681
+ * This helper class provides integration with the OpenAI GPT-3.5 or 4 language model for generating responses to questions or prompts within the context of web pages. It allows you to interact with the GPT-3.5 model to obtain intelligent responses based on HTML fragments or general prompts.
2682
+ * This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDrvier to ensure the HTML context is available.
2683
+ *
2684
+ * ## Configuration
2685
+ *
2686
+ * This helper should be configured in codecept.json or codecept.conf.js
2687
+ *
2688
+ * * `chunkSize`: (optional, default: 80000) - The maximum number of characters to send to the OpenAI API at once. We split HTML fragments by 8000 chars to not exceed token limit. Increase this value if you use GPT-4.
2689
+ */
2690
+ class OpenAITs {
2691
+ /**
2692
+ * Asks the OpenAI GPT language model a question based on the provided prompt within the context of the current page's HTML.
2693
+ *
2694
+ * ```js
2695
+ * I.askGptOnPage('what does this page do?');
2696
+ * ```
2697
+ * @param prompt - The question or prompt to ask the GPT model.
2698
+ * @returns - A Promise that resolves to the generated responses from the GPT model, joined by newlines.
2699
+ */
2700
+ askGptOnPage(prompt: string): Promise<string>;
2701
+ /**
2702
+ * Asks the OpenAI GPT-3.5 language model a question based on the provided prompt within the context of a specific HTML fragment on the current page.
2703
+ *
2704
+ * ```js
2705
+ * I.askGptOnPageFragment('describe features of this screen', '.screen');
2706
+ * ```
2707
+ * @param prompt - The question or prompt to ask the GPT-3.5 model.
2708
+ * @param locator - The locator or selector used to identify the HTML fragment on the page.
2709
+ * @returns - A Promise that resolves to the generated response from the GPT model.
2710
+ */
2711
+ askGptOnPageFragment(prompt: string, locator: string): Promise<string>;
2712
+ /**
2713
+ * Send a general request to ChatGPT and return response.
2714
+ * @returns - A Promise that resolves to the generated response from the GPT model.
2715
+ */
2716
+ askGptGeneralPrompt(prompt: string): Promise<string>;
2717
+ }
2674
2718
  /**
2675
2719
  * Uses [Playwright](https://github.com/microsoft/playwright) library to run tests inside:
2676
2720
  *
@@ -2705,7 +2749,7 @@ declare namespace CodeceptJS {
2705
2749
  *
2706
2750
  * #### Trace Recording Customization
2707
2751
  *
2708
- * Trace recording provides a complete information on test execution and includes DOM snapshots, screenshots, and network requests logged during run.
2752
+ * Trace recording provides complete information on test execution and includes DOM snapshots, screenshots, and network requests logged during run.
2709
2753
  * Traces will be saved to `output/trace`
2710
2754
  *
2711
2755
  * * `trace`: enables trace recording for failed tests; trace are saved into `output/trace` folder
@@ -2999,6 +3043,39 @@ declare namespace CodeceptJS {
2999
3043
  * ⚠️ returns a _promise_ which is synchronized internally by recorder
3000
3044
  */
3001
3045
  moveCursorTo(locator: CodeceptJS.LocatorOrString, offsetX?: number, offsetY?: number): Promise<any>;
3046
+ /**
3047
+ * Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the matching element.
3048
+ * @param locator - field located by label|name|CSS|XPath|strict locator.
3049
+ * @param [options] - [Additional options](https://playwright.dev/docs/api/class-locator#locator-focus) for available options object as 2nd argument.
3050
+ *
3051
+ * Examples:
3052
+ *
3053
+ * ```js
3054
+ * I.dontSee('#add-to-cart-btn');
3055
+ * I.focus('#product-tile')
3056
+ * I.see('#add-to-cart-bnt');
3057
+ * ```
3058
+ */
3059
+ focus(locator: CodeceptJS.LocatorOrString, options?: any): Promise<any>;
3060
+ /**
3061
+ * Remove focus from a text input, button, etc
3062
+ * Calls [blur](https://playwright.dev/docs/api/class-locator#locator-blur) on the element.
3063
+ * @param locator - field located by label|name|CSS|XPath|strict locator.
3064
+ * @param [options] - [Additional options](https://playwright.dev/docs/api/class-locator#locator-blur) for available options object as 2nd argument.
3065
+ *
3066
+ * Examples:
3067
+ *
3068
+ * ```js
3069
+ * I.blur('.text-area')
3070
+ * ```
3071
+ * ```js
3072
+ * //element `#product-tile` is focused
3073
+ * I.see('#add-to-cart-btn');
3074
+ * I.blur('#product-tile')
3075
+ * I.dontSee('#add-to-cart-btn');
3076
+ * ```
3077
+ */
3078
+ blur(locator: CodeceptJS.LocatorOrString, options?: any): Promise<any>;
3002
3079
  /**
3003
3080
  * Drag an item to a destination element.
3004
3081
  *
@@ -3015,7 +3092,7 @@ declare namespace CodeceptJS {
3015
3092
  * I.dragAndDrop('img.src', 'img.dst', { sourcePosition: {x: 10, y: 10} })
3016
3093
  * ```
3017
3094
  *
3018
- * > By default option `force: true` is set
3095
+ * > When no option is set, custom drag and drop would be used, to use the dragAndDrop API from Playwright, please set options, for example `force: true`
3019
3096
  */
3020
3097
  dragAndDrop(srcElement: LocatorOrString, destElement: LocatorOrString, options?: any): Promise<any>;
3021
3098
  /**
@@ -3299,7 +3376,7 @@ declare namespace CodeceptJS {
3299
3376
  * @param locator - clickable link or button located by text, or any element located by CSS|XPath|strict locator.
3300
3377
  * @param [context = null] - (optional, `null` by default) element to search in CSS|XPath|Strict locator.
3301
3378
  * ⚠️ returns a _promise_ which is synchronized internally by recorder
3302
- * @param [opts] - [Additional options](https://playwright.dev/docs/api/class-page#page-click) for click available as 3rd argument.
3379
+ * @param [options] - [Additional options](https://playwright.dev/docs/api/class-page#page-click) for click available as 3rd argument.
3303
3380
  *
3304
3381
  * Examples:
3305
3382
  *
@@ -3311,7 +3388,7 @@ declare namespace CodeceptJS {
3311
3388
  * I.click('.edit', null, { modifiers: ['Ctrl'] } )
3312
3389
  * ```
3313
3390
  */
3314
- click(locator: CodeceptJS.LocatorOrString, context?: CodeceptJS.LocatorOrString | null, opts?: any): Promise<any>;
3391
+ click(locator: CodeceptJS.LocatorOrString, context?: CodeceptJS.LocatorOrString | null, options?: any): Promise<any>;
3315
3392
  /**
3316
3393
  * Clicks link and waits for navigation (deprecated)
3317
3394
  */
@@ -3562,6 +3639,9 @@ declare namespace CodeceptJS {
3562
3639
  *
3563
3640
  * // passing in an array
3564
3641
  * I.type(['T', 'E', 'X', 'T']);
3642
+ *
3643
+ * // passing a secret
3644
+ * I.type(secret('123456'));
3565
3645
  * ```
3566
3646
  * @param key - or array of keys to type.
3567
3647
  * @param [delay = null] - (optional) delay in ms between key presses
@@ -3588,23 +3668,28 @@ declare namespace CodeceptJS {
3588
3668
  */
3589
3669
  fillField(field: CodeceptJS.LocatorOrString, value: CodeceptJS.StringOrSecret): Promise<any>;
3590
3670
  /**
3591
- * Clears a `<textarea>` or text `<input>` element's value.
3671
+ * Clear the <input>, <textarea> or [contenteditable] .
3672
+ * @param locator - field located by label|name|CSS|XPath|strict locator.
3673
+ * @param [options] - [Additional options](https://playwright.dev/docs/api/class-locator#locator-clear) for available options object as 2nd argument.
3674
+ *
3675
+ * Examples:
3592
3676
  *
3593
3677
  * ```js
3594
- * I.clearField('Email');
3595
- * I.clearField('user[email]');
3596
- * I.clearField('#email');
3678
+ * I.clearField('.text-area')
3679
+ * ```
3680
+ * ```js
3681
+ * I.clearField('#submit', { force: true }) // force to bypass the [actionability](https://playwright.dev/docs/actionability) checks.
3597
3682
  * ```
3598
- * @param editable - field located by label|name|CSS|XPath|strict locator.
3599
- * ⚠️ returns a _promise_ which is synchronized internally by recorder.
3600
3683
  */
3601
- clearField(editable: LocatorOrString): Promise<any>;
3684
+ clearField(locator: CodeceptJS.LocatorOrString, options?: any): Promise<any>;
3602
3685
  /**
3603
3686
  * Appends text to a input field or textarea.
3604
3687
  * Field is located by name, label, CSS or XPath
3605
3688
  *
3606
3689
  * ```js
3607
3690
  * I.appendField('#myTextField', 'appended');
3691
+ * // typing secret
3692
+ * I.appendField('password', secret('123456'));
3608
3693
  * ```
3609
3694
  * @param field - located by label|name|CSS|XPath|strict locator
3610
3695
  * @param value - text value to append.
@@ -4334,7 +4419,7 @@ declare namespace CodeceptJS {
4334
4419
  *
4335
4420
  * See [Playwright's reference](https://playwright.dev/docs/api/class-page?_highlight=waitfornavi#pagewaitfornavigationoptions)
4336
4421
  */
4337
- waitForNavigation(opts: any): Promise<any>;
4422
+ waitForNavigation(options: any): Promise<any>;
4338
4423
  /**
4339
4424
  * Waits for an element to become not attached to the DOM on a page (by default waits for 1sec).
4340
4425
  * Element can be located by CSS or XPath.
@@ -4859,6 +4944,8 @@ declare namespace CodeceptJS {
4859
4944
  *
4860
4945
  * ```js
4861
4946
  * I.appendField('#myTextField', 'appended');
4947
+ * // typing secret
4948
+ * I.appendField('password', secret('123456'));
4862
4949
  * ```
4863
4950
  * @param field - located by label|name|CSS|XPath|strict locator
4864
4951
  * @param value - text value to append.
@@ -6567,6 +6654,9 @@ declare namespace CodeceptJS {
6567
6654
  *
6568
6655
  * // passing in an array
6569
6656
  * I.type(['T', 'E', 'X', 'T']);
6657
+ *
6658
+ * // passing a secret
6659
+ * I.type(secret('123456'));
6570
6660
  * ```
6571
6661
  * @param key - or array of keys to type.
6572
6662
  * @param [delay = null] - (optional) delay in ms between key presses
@@ -6612,6 +6702,8 @@ declare namespace CodeceptJS {
6612
6702
  *
6613
6703
  * ```js
6614
6704
  * I.appendField('#myTextField', 'appended');
6705
+ * // typing secret
6706
+ * I.appendField('password', secret('123456'));
6615
6707
  * ```
6616
6708
  * @param field - located by label|name|CSS|XPath|strict locator
6617
6709
  * @param value - text value to append.
@@ -7471,7 +7563,8 @@ declare namespace CodeceptJS {
7471
7563
  * endpoint: 'http://site.com/api',
7472
7564
  * prettyPrintJson: true,
7473
7565
  * onRequest: (request) => {
7474
- * request.headers.auth = '123';
7566
+ * request.headers.auth = '123';
7567
+ * }
7475
7568
  * }
7476
7569
  * }
7477
7570
  * }
@@ -7530,7 +7623,7 @@ declare namespace CodeceptJS {
7530
7623
  * ```js
7531
7624
  * I.sendGetRequest('/api/users.json');
7532
7625
  * ```
7533
- * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
7626
+ * @param [headers = {}] - the headers object to be sent. By default, it is sent as an empty object
7534
7627
  * @returns response
7535
7628
  */
7536
7629
  sendGetRequest(url: any, headers?: any): Promise<any>;
@@ -7544,8 +7637,8 @@ declare namespace CodeceptJS {
7544
7637
  * I.sendPostRequest('/api/users.json', secret({ "email": "user@user.com" }));
7545
7638
  *
7546
7639
  * ```
7547
- * @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
7548
- * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
7640
+ * @param [payload = {}] - the payload to be sent. By default, it is sent as an empty object
7641
+ * @param [headers = {}] - the headers object to be sent. By default, it is sent as an empty object
7549
7642
  * @returns response
7550
7643
  */
7551
7644
  sendPostRequest(url: any, payload?: any, headers?: any): Promise<any>;
@@ -7585,7 +7678,7 @@ declare namespace CodeceptJS {
7585
7678
  * ```js
7586
7679
  * I.sendDeleteRequest('/api/users/1');
7587
7680
  * ```
7588
- * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
7681
+ * @param [headers = {}] - the headers object to be sent. By default, it is sent as an empty object
7589
7682
  * @returns response
7590
7683
  */
7591
7684
  sendDeleteRequest(url: any, headers?: any): Promise<any>;
@@ -7859,6 +7952,8 @@ declare namespace CodeceptJS {
7859
7952
  *
7860
7953
  * ```js
7861
7954
  * I.appendField('#myTextField', 'appended');
7955
+ * // typing secret
7956
+ * I.appendField('password', secret('123456'));
7862
7957
  * ```
7863
7958
  * @param field - located by label|name|CSS|XPath|strict locator
7864
7959
  * @param value - text value to append.
@@ -8966,7 +9061,7 @@ declare namespace CodeceptJS {
8966
9061
  */
8967
9062
  _locate(locator: CodeceptJS.LocatorOrString): Promise<any>;
8968
9063
  /**
8969
- * Find a checkbox by providing human readable text:
9064
+ * Find a checkbox by providing human-readable text:
8970
9065
  *
8971
9066
  * ```js
8972
9067
  * this.helpers['WebDriver']._locateCheckable('I agree with terms and conditions').then // ...
@@ -8975,7 +9070,7 @@ declare namespace CodeceptJS {
8975
9070
  */
8976
9071
  _locateCheckable(locator: CodeceptJS.LocatorOrString): Promise<any>;
8977
9072
  /**
8978
- * Find a clickable element by providing human readable text:
9073
+ * Find a clickable element by providing human-readable text:
8979
9074
  *
8980
9075
  * ```js
8981
9076
  * const els = await this.helpers.WebDriver._locateClickable('Next page');
@@ -8985,7 +9080,7 @@ declare namespace CodeceptJS {
8985
9080
  */
8986
9081
  _locateClickable(locator: CodeceptJS.LocatorOrString): Promise<any>;
8987
9082
  /**
8988
- * Find field elements by providing human readable text:
9083
+ * Find field elements by providing human-readable text:
8989
9084
  *
8990
9085
  * ```js
8991
9086
  * this.helpers['WebDriver']._locateFields('Your email').then // ...
@@ -9168,6 +9263,8 @@ declare namespace CodeceptJS {
9168
9263
  *
9169
9264
  * ```js
9170
9265
  * I.appendField('#myTextField', 'appended');
9266
+ * // typing secret
9267
+ * I.appendField('password', secret('123456'));
9171
9268
  * ```
9172
9269
  * @param field - located by label|name|CSS|XPath|strict locator
9173
9270
  * @param value - text value to append.
@@ -10047,6 +10144,9 @@ declare namespace CodeceptJS {
10047
10144
  *
10048
10145
  * // passing in an array
10049
10146
  * I.type(['T', 'E', 'X', 'T']);
10147
+ *
10148
+ * // passing a secret
10149
+ * I.type(secret('123456'));
10050
10150
  * ```
10051
10151
  * @param key - or array of keys to type.
10052
10152
  * @param [delay = null] - (optional) delay in ms between key presses