codeceptjs 3.5.1 → 3.5.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.5.1",
3
+ "version": "3.5.3",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -59,13 +59,13 @@
59
59
  "prepare": "husky install"
60
60
  },
61
61
  "dependencies": {
62
- "@codeceptjs/configure": "^0.8.0",
62
+ "@codeceptjs/configure": "^0.10.0",
63
63
  "@codeceptjs/helper": "^1.0.2",
64
64
  "@cucumber/cucumber-expressions": "^16",
65
65
  "@cucumber/gherkin": "^26",
66
66
  "@cucumber/messages": "^21.0.1",
67
67
  "@xmldom/xmldom": "^0.7.9",
68
- "acorn": "^7.4.1",
68
+ "acorn": "^8.10.0",
69
69
  "arrify": "^2.0.1",
70
70
  "axios": "^1.3.3",
71
71
  "chai": "^4.3.6",
@@ -75,7 +75,7 @@
75
75
  "cross-spawn": "^7.0.3",
76
76
  "css-to-xpath": "^0.1.0",
77
77
  "envinfo": "^7.8.1",
78
- "escape-string-regexp": "^1.0.3",
78
+ "escape-string-regexp": "^4.0.0",
79
79
  "figures": "^3.2.0",
80
80
  "fn-args": "^4.0.0",
81
81
  "fs-extra": "^8.1.0",
@@ -115,27 +115,25 @@
115
115
  "contributor-faces": "^1.0.3",
116
116
  "documentation": "^12.3.0",
117
117
  "dtslint": "^4.1.6",
118
- "electron": "^12.2.3",
119
- "eslint": "^6.8.0",
118
+ "electron": "^25.2.0",
119
+ "eslint": "^8.45.0",
120
120
  "eslint-config-airbnb-base": "^15.0.0",
121
121
  "eslint-plugin-import": "^2.25.4",
122
122
  "eslint-plugin-mocha": "^6.3.0",
123
123
  "expect": "^26.6.2",
124
124
  "express": "^4.17.2",
125
- "form-data": "^3.0.1",
126
125
  "graphql": "^14.6.0",
127
126
  "husky": "^8.0.1",
128
127
  "inquirer-test": "^2.0.1",
129
128
  "jsdoc": "^3.6.10",
130
129
  "jsdoc-typeof-plugin": "^1.0.0",
131
130
  "json-server": "^0.10.1",
132
- "nightmare": "^3.0.2",
133
131
  "playwright": "^1.35.1",
134
132
  "puppeteer": "^10.4.0",
135
133
  "qrcode-terminal": "^0.12.0",
136
134
  "rosie": "^2.1.0",
137
135
  "runok": "^0.9.2",
138
- "sinon": "^9.2.4",
136
+ "sinon": "^15.2.0",
139
137
  "sinon-chai": "^3.7.0",
140
138
  "testcafe": "^2.1.0",
141
139
  "ts-morph": "^3.1.3",
@@ -147,7 +145,7 @@
147
145
  "wdio-docker-service": "^1.5.0",
148
146
  "webdriverio": "^8.3.8",
149
147
  "xml2js": "^0.6.0",
150
- "xmldom": "^0.5.0",
148
+ "xmldom": "^0.6.0",
151
149
  "xpath": "0.0.27"
152
150
  },
153
151
  "engines": {
@@ -524,7 +524,6 @@ declare const After: CodeceptJS.IHook;
524
524
  declare const __: any
525
525
 
526
526
  interface Window {
527
- codeceptjs: typeof CodeceptJS.browserCodecept;
528
527
  resq: any;
529
528
  }
530
529
 
@@ -4519,6 +4519,133 @@ declare namespace CodeceptJS {
4519
4519
  * @param [handler] - a function to process reques
4520
4520
  */
4521
4521
  stopMockingRoute(url?: string | RegExp, handler?: (...params: any[]) => any): Promise<any>;
4522
+ /**
4523
+ * Starts recording of network traffic.
4524
+ * This also resets recorded network requests.
4525
+ *
4526
+ * ```js
4527
+ * I.startRecordingTraffic();
4528
+ * ```
4529
+ */
4530
+ startRecordingTraffic(): Promise<void>;
4531
+ /**
4532
+ * Grab the recording network traffics
4533
+ */
4534
+ grabRecordedNetworkTraffics(): Promise<any>;
4535
+ /**
4536
+ * Blocks traffic for URL.
4537
+ *
4538
+ * Examples:
4539
+ *
4540
+ * ```js
4541
+ * I.blockTraffic('http://example.com/css/style.css');
4542
+ * I.blockTraffic('http://example.com/css/*.css');
4543
+ * I.blockTraffic('http://example.com/**');
4544
+ * I.blockTraffic(/\.css$/);
4545
+ * ```
4546
+ * @param url - URL to block . URL can contain * for wildcards. Example: https://www.example.com** to block all traffic for that domain. Regexp are also supported.
4547
+ */
4548
+ blockTraffic(url: any): Promise<any>;
4549
+ /**
4550
+ * Mocks traffic for URL(s).
4551
+ * This is a powerful feature to manipulate network traffic. Can be used e.g. to stabilize your tests, speed up your tests or as a last resort to make some test scenarios even possible.
4552
+ *
4553
+ * Examples:
4554
+ *
4555
+ * ```js
4556
+ * I.mockTraffic('/api/users/1', '{ id: 1, name: 'John Doe' }');
4557
+ * I.mockTraffic('/api/users/*', JSON.stringify({ id: 1, name: 'John Doe' }));
4558
+ * I.mockTraffic([/^https://api.example.com/v1/, 'https://api.example.com/v2/**'], 'Internal Server Error', 'text/html');
4559
+ * ```
4560
+ * @param urls - string|Array These are the URL(s) to mock, e.g. "/fooapi/*" or "['/fooapi_1/*', '/barapi_2/*']". Regular expressions are also supported.
4561
+ * @param responseString - string The string to return in fake response's body.
4562
+ * @param contentType - Content type of fake response. If not specified default value 'application/json' is used.
4563
+ */
4564
+ mockTraffic(urls: any, responseString: any, contentType?: any): Promise<any>;
4565
+ /**
4566
+ * Resets all recorded network requests.
4567
+ */
4568
+ flushNetworkTraffics(): Promise<any>;
4569
+ /**
4570
+ * Stops recording of network traffic. Recorded traffic is not flashed.
4571
+ *
4572
+ * ```js
4573
+ * I.stopRecordingTraffic();
4574
+ * ```
4575
+ */
4576
+ stopRecordingTraffic(): Promise<any>;
4577
+ /**
4578
+ * Verifies that a certain request is part of network traffic.
4579
+ *
4580
+ * ```js
4581
+ * // checking the request url contains certain query strings
4582
+ * I.amOnPage('https://openai.com/blog/chatgpt');
4583
+ * I.startRecordingTraffic();
4584
+ * await I.seeTraffic({
4585
+ * name: 'sentry event',
4586
+ * url: 'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600',
4587
+ * parameters: {
4588
+ * width: '1919',
4589
+ * height: '1138',
4590
+ * },
4591
+ * });
4592
+ * ```
4593
+ *
4594
+ * ```js
4595
+ * // checking the request url contains certain post data
4596
+ * I.amOnPage('https://openai.com/blog/chatgpt');
4597
+ * I.startRecordingTraffic();
4598
+ * await I.seeTraffic({
4599
+ * name: 'event',
4600
+ * url: 'https://cloudflareinsights.com/cdn-cgi/rum',
4601
+ * requestPostData: {
4602
+ * st: 2,
4603
+ * },
4604
+ * });
4605
+ * ```
4606
+ * @param opts - options when checking the traffic network.
4607
+ * @param opts.name - A name of that request. Can be any value. Only relevant to have a more meaningful error message in case of fail.
4608
+ * @param opts.url - Expected URL of request in network traffic
4609
+ * @param [opts.parameters] - Expected parameters of that request in network traffic
4610
+ * @param [opts.requestPostData] - Expected that request contains post data in network traffic
4611
+ * @param [opts.timeout] - Timeout to wait for request in seconds. Default is 10 seconds.
4612
+ */
4613
+ seeTraffic(opts: {
4614
+ name: string;
4615
+ url: string;
4616
+ parameters?: any;
4617
+ requestPostData?: any;
4618
+ timeout?: number;
4619
+ }): Promise<any>;
4620
+ /**
4621
+ * Returns full URL of request matching parameter "urlMatch".
4622
+ * @param urlMatch - Expected URL of request in network traffic. Can be a string or a regular expression.
4623
+ *
4624
+ * Examples:
4625
+ *
4626
+ * ```js
4627
+ * I.grabTrafficUrl('https://api.example.com/session');
4628
+ * I.grabTrafficUrl(/session.*start/);
4629
+ * ```
4630
+ */
4631
+ grabTrafficUrl(urlMatch: string | RegExp): Promise<any>;
4632
+ /**
4633
+ * Verifies that a certain request is not part of network traffic.
4634
+ *
4635
+ * Examples:
4636
+ *
4637
+ * ```js
4638
+ * I.dontSeeTraffic({ name: 'Unexpected API Call', url: 'https://api.example.com' });
4639
+ * I.dontSeeTraffic({ name: 'Unexpected API Call of "user" endpoint', url: /api.example.com.*user/ });
4640
+ * ```
4641
+ * @param opts - options when checking the traffic network.
4642
+ * @param opts.name - A name of that request. Can be any value. Only relevant to have a more meaningful error message in case of fail.
4643
+ * @param opts.url - Expected URL of request in network traffic. Can be a string or a regular expression.
4644
+ */
4645
+ dontSeeTraffic(opts: {
4646
+ name: string;
4647
+ url: string | RegExp;
4648
+ }): Promise<any>;
4522
4649
  }
4523
4650
  /**
4524
4651
  * This helper works the same as MockRequest helper. It has been included for backwards compatibility
@@ -4602,6 +4602,133 @@ declare namespace CodeceptJS {
4602
4602
  * @param [handler] - a function to process reques
4603
4603
  */
4604
4604
  stopMockingRoute(url?: string | RegExp, handler?: (...params: any[]) => any): void;
4605
+ /**
4606
+ * Starts recording of network traffic.
4607
+ * This also resets recorded network requests.
4608
+ *
4609
+ * ```js
4610
+ * I.startRecordingTraffic();
4611
+ * ```
4612
+ */
4613
+ startRecordingTraffic(): Promise<void>;
4614
+ /**
4615
+ * Grab the recording network traffics
4616
+ */
4617
+ grabRecordedNetworkTraffics(): any[];
4618
+ /**
4619
+ * Blocks traffic for URL.
4620
+ *
4621
+ * Examples:
4622
+ *
4623
+ * ```js
4624
+ * I.blockTraffic('http://example.com/css/style.css');
4625
+ * I.blockTraffic('http://example.com/css/*.css');
4626
+ * I.blockTraffic('http://example.com/**');
4627
+ * I.blockTraffic(/\.css$/);
4628
+ * ```
4629
+ * @param url - URL to block . URL can contain * for wildcards. Example: https://www.example.com** to block all traffic for that domain. Regexp are also supported.
4630
+ */
4631
+ blockTraffic(url: any): void;
4632
+ /**
4633
+ * Mocks traffic for URL(s).
4634
+ * This is a powerful feature to manipulate network traffic. Can be used e.g. to stabilize your tests, speed up your tests or as a last resort to make some test scenarios even possible.
4635
+ *
4636
+ * Examples:
4637
+ *
4638
+ * ```js
4639
+ * I.mockTraffic('/api/users/1', '{ id: 1, name: 'John Doe' }');
4640
+ * I.mockTraffic('/api/users/*', JSON.stringify({ id: 1, name: 'John Doe' }));
4641
+ * I.mockTraffic([/^https://api.example.com/v1/, 'https://api.example.com/v2/**'], 'Internal Server Error', 'text/html');
4642
+ * ```
4643
+ * @param urls - string|Array These are the URL(s) to mock, e.g. "/fooapi/*" or "['/fooapi_1/*', '/barapi_2/*']". Regular expressions are also supported.
4644
+ * @param responseString - string The string to return in fake response's body.
4645
+ * @param contentType - Content type of fake response. If not specified default value 'application/json' is used.
4646
+ */
4647
+ mockTraffic(urls: any, responseString: any, contentType?: any): void;
4648
+ /**
4649
+ * Resets all recorded network requests.
4650
+ */
4651
+ flushNetworkTraffics(): void;
4652
+ /**
4653
+ * Stops recording of network traffic. Recorded traffic is not flashed.
4654
+ *
4655
+ * ```js
4656
+ * I.stopRecordingTraffic();
4657
+ * ```
4658
+ */
4659
+ stopRecordingTraffic(): void;
4660
+ /**
4661
+ * Verifies that a certain request is part of network traffic.
4662
+ *
4663
+ * ```js
4664
+ * // checking the request url contains certain query strings
4665
+ * I.amOnPage('https://openai.com/blog/chatgpt');
4666
+ * I.startRecordingTraffic();
4667
+ * await I.seeTraffic({
4668
+ * name: 'sentry event',
4669
+ * url: 'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600',
4670
+ * parameters: {
4671
+ * width: '1919',
4672
+ * height: '1138',
4673
+ * },
4674
+ * });
4675
+ * ```
4676
+ *
4677
+ * ```js
4678
+ * // checking the request url contains certain post data
4679
+ * I.amOnPage('https://openai.com/blog/chatgpt');
4680
+ * I.startRecordingTraffic();
4681
+ * await I.seeTraffic({
4682
+ * name: 'event',
4683
+ * url: 'https://cloudflareinsights.com/cdn-cgi/rum',
4684
+ * requestPostData: {
4685
+ * st: 2,
4686
+ * },
4687
+ * });
4688
+ * ```
4689
+ * @param opts - options when checking the traffic network.
4690
+ * @param opts.name - A name of that request. Can be any value. Only relevant to have a more meaningful error message in case of fail.
4691
+ * @param opts.url - Expected URL of request in network traffic
4692
+ * @param [opts.parameters] - Expected parameters of that request in network traffic
4693
+ * @param [opts.requestPostData] - Expected that request contains post data in network traffic
4694
+ * @param [opts.timeout] - Timeout to wait for request in seconds. Default is 10 seconds.
4695
+ */
4696
+ seeTraffic(opts: {
4697
+ name: string;
4698
+ url: string;
4699
+ parameters?: any;
4700
+ requestPostData?: any;
4701
+ timeout?: number;
4702
+ }): Promise<any>;
4703
+ /**
4704
+ * Returns full URL of request matching parameter "urlMatch".
4705
+ * @param urlMatch - Expected URL of request in network traffic. Can be a string or a regular expression.
4706
+ *
4707
+ * Examples:
4708
+ *
4709
+ * ```js
4710
+ * I.grabTrafficUrl('https://api.example.com/session');
4711
+ * I.grabTrafficUrl(/session.*start/);
4712
+ * ```
4713
+ */
4714
+ grabTrafficUrl(urlMatch: string | RegExp): Promise<any>;
4715
+ /**
4716
+ * Verifies that a certain request is not part of network traffic.
4717
+ *
4718
+ * Examples:
4719
+ *
4720
+ * ```js
4721
+ * I.dontSeeTraffic({ name: 'Unexpected API Call', url: 'https://api.example.com' });
4722
+ * I.dontSeeTraffic({ name: 'Unexpected API Call of "user" endpoint', url: /api.example.com.*user/ });
4723
+ * ```
4724
+ * @param opts - options when checking the traffic network.
4725
+ * @param opts.name - A name of that request. Can be any value. Only relevant to have a more meaningful error message in case of fail.
4726
+ * @param opts.url - Expected URL of request in network traffic. Can be a string or a regular expression.
4727
+ */
4728
+ dontSeeTraffic(opts: {
4729
+ name: string;
4730
+ url: string | RegExp;
4731
+ }): void;
4605
4732
  }
4606
4733
  /**
4607
4734
  * This helper works the same as MockRequest helper. It has been included for backwards compatibility
@@ -11114,31 +11241,6 @@ declare namespace CodeceptJS {
11114
11241
  */
11115
11242
  function cleanDispatcher(): void;
11116
11243
  }
11117
- namespace browserCodecept {
11118
- /**
11119
- * all found elements are stored here for reuse
11120
- */
11121
- var elements: Node[];
11122
- /**
11123
- * global context changer
11124
- */
11125
- var within: Node;
11126
- /**
11127
- * finders
11128
- */
11129
- function fetchElement(id: number): Node;
11130
- function findAndStoreElements(by: string, locator: CodeceptJS.ILocator, contextEl?: any): number[];
11131
- function findAndStoreElement(by: string, locator: CodeceptJS.ILocator, contextEl?: any): number | undefined;
11132
- function setWithin(by: string, locator: CodeceptJS.ILocator): void;
11133
- function findElements(by: string, locator: CodeceptJS.ILocator, contextEl?: any): Node[];
11134
- function findElement(by: string, locator: CodeceptJS.ILocator, context?: any): Node;
11135
- function clickEl(el: number): boolean;
11136
- function doubleClickEl(el: number): void;
11137
- function hoverEl(el: number, x: number | undefined, y: number | undefined): void;
11138
- function rightClickEl(el: number): void;
11139
- function checkEl(el: number): boolean | undefined;
11140
- function unCheckEl(el: number): boolean;
11141
- }
11142
11244
  /**
11143
11245
  * Index file for loading CodeceptJS programmatically.
11144
11246
  *
package/docs/nightmare.md DELETED
@@ -1,223 +0,0 @@
1
- ---
2
- permalink: /nightmare
3
- title: Testing with Nightmare
4
- ---
5
-
6
- # Testing with Nightmare
7
-
8
- Selenium WebDriver is considered to be standard for end to end testing of web applications.
9
- Despite its popularity it have its drawbacks, it requires a real browser and Selenium server to control it.
10
- This hardens setting it up testing environment for CI server and slows down test execution.
11
-
12
- Is there a sane alternative to Selenium?
13
-
14
- Yes, how about [NightmareJS](https://www.nightmarejs.org)?
15
-
16
- It is modern Electron based testing framework which allows to execute tests in headless mode as well as in window mode for debug purposes.
17
- This makes Nightmare very useful, much more handy than PhantomJS. Nightmare is in active development and has nice API for writing acceptance tests.
18
- Unfortunately, as all other JavaScript testing frameworks it has its own very custom API.
19
- What if you choose it for a project and suddenly you realize that you need something more powerful, like Selenium?
20
- Yes, that might be a problem if you are not using CodeceptJS.
21
- The one idea behind CodeceptJS is to unify different testing backends under one API, so you could easily write tests the same way no matter what engines you use: webdriverio, Protractor, or Nightmare.
22
-
23
- Compare a test written using Nightmare API:
24
-
25
- ```js
26
- nightmare
27
- .goto('http://yahoo.com')
28
- .type('form[action*="/search"] [name=p]', 'github nightmare')
29
- .click('form[action*="/search"] [type=submit]')
30
- .wait('#main')
31
- .evaluate(function () {
32
- return document.querySelector('#main .searchCenterMiddle li a').href
33
- })
34
- ```
35
-
36
- with a similar CodeceptJS test:
37
-
38
- ```js
39
- I.amOnPage('http://yahoo.com');
40
- I.fillField('p', 'github nightmare');
41
- I.click('Search Web');
42
- I.waitForElement('#main');
43
- I.seeElement('#main .searchCenterMiddle li a');
44
- I.seeElement("//a[contains(@href,'github.com/segmentio/nightmare')]");
45
- I.see('segmentio/nightmare','#main li a');
46
- ```
47
-
48
- NightmareJS support only CSS locators for web elements, while CodeceptJS improves it to use XPath as well.
49
- This is how form can be located by labels, and buttons by text in examples above. It is done by injecting
50
- client-side scrips (for element location) to every loaded page. Also all events like click, doubleClick, keyPress are **simulated** by JavaScript,
51
- this makes testing less relevant, as they are not native to operating systems.
52
-
53
- ## How Fast Is Nightmare JS?
54
-
55
- Let's execute the test above within WebDriver using headless Firefox + Selenium Server packed in Docker container.
56
-
57
- ```sh
58
- docker run -d -p 4444:4444 selenium/standalone-firefox:2.53.0
59
- codeceptjs run yahoo_test.js --steps
60
- ```
61
-
62
- This provides use with output:
63
-
64
- ```sh
65
- Yahoo basic test
66
- > WebDriver._before
67
- • I am on page "http://yahoo.com"
68
- • I fill field "p", "github nightmare"
69
- • I click "Search Web"
70
- • I wait for element "#main", 2
71
- • I see element "#main .searchCenterMiddle li a"
72
- • I see "segmentio/nightmare", "li a"
73
- ✓ OK in 17591ms
74
- ```
75
-
76
- When we switch helper to Nightmare:
77
-
78
- ```sh
79
- Yahoo basic test
80
- > Nightmare._before
81
- • I am on page "http://yahoo.com"
82
- • I fill field "p", "github nightmare"
83
- • I click "Search Web"
84
- • I wait for element "#main", 2
85
- • I see element "#main .searchCenterMiddle li a"
86
- • I see "segmentio/nightmare", "li a"
87
- ✓ OK in 5490ms
88
- ```
89
-
90
- As you see the Nightmare test was almost **3 times faster** than Selenium test.
91
- Sure, this can't be taken as a valuable benchmark but more like a proof of concept.
92
-
93
- ## Setup
94
-
95
- To start you need CodeceptJS with nightmare package installed.
96
-
97
- ```bash
98
- npm install -g nightmare
99
- ```
100
-
101
- And a basic project initialized
102
-
103
- ```sh
104
- codeceptjs init
105
- ```
106
-
107
- You will be asked for a Helper to use, you should select Nightmare and provide url of a website you are testing.
108
- Setup process is explained on [QuickStart page](https://codecept.io/quickstart/).
109
-
110
- (If you already have CodeceptJS project, just install nightmare globally or locally and enable it in config)
111
-
112
- ## Configuring Nightmare
113
-
114
- Enable `Nightmare` helper in `codecept.json` config:
115
-
116
- ```js
117
- { // ..
118
- "helpers": {
119
- "Nightmare": {
120
- "url": "http://localhost",
121
- "show": false,
122
- "restart": false
123
- }
124
- }
125
- // ..
126
- }
127
- ```
128
-
129
- Turn on the `show` option if you want to follow test progress in a window. This is very useful for debugging.
130
- All other options can be taken from [NightmareJS API](https://github.com/segmentio/nightmare#api).
131
-
132
- Turn off the `restart` option if you want to run your suite in a single browser instance.
133
-
134
- Option `waitForAction` defines how long to wait after a click, doubleClick or pressKey action is performed.
135
- Test execution may happen much faster than the response is rendered, so make sure you set a proper delay value.
136
- By default CodeceptJS waits for 500ms.
137
-
138
- ## Opening a Web Page
139
-
140
- Nightmare provides you with more control to browser engine than Selenium does.
141
- This allows you to use headers in your tests. For instance, CodeceptJS provides `haveHeader` method
142
- to set default headers for all your HTTP requests:
143
-
144
- ```js
145
- I.haveHeader('x-tested-with', 'codeceptjs');
146
- ```
147
-
148
- When opening a web page you can set headers as well. `amOnPage` methods can take headers as second parameter:
149
-
150
- ```js
151
- // use basic http auth
152
- I.amOnPage('/admin', { 'Authorization': 'Basic '+token });
153
- ```
154
-
155
- As a small bonus: all `console.log` calls on a page will be also shown in `--debug` mode.
156
-
157
- ## Manipulating Web Page
158
-
159
- Nightmare helper is supposed to work in the same manner as WebDriver or Protractor.
160
- This means that all CodeceptJS actions like `click`, `fillField`, `selectOption` and others are supposed to work in the very same manner.
161
- They are expressive and flexible to accept CSS, XPath, names, values, or strict locators. Follow the helper reference for detailed description.
162
-
163
- Assertions start with `see` prefix. You can check text on a page, elements on page and others.
164
-
165
- ## Extending Nightmare Helper
166
-
167
- CodeceptJS allows you to define and connect own helpers. If some functionality of
168
- Nightmare helper is missing you can easily create `ExtendedNightmare` helper by running:
169
-
170
- ```sh
171
- codeceptjs gh
172
- ```
173
-
174
- Learn more about [Helpers](https://codecept.io/helpers/).
175
-
176
- Nightmare instance can be accessed by custom helper:
177
-
178
- ```js
179
- // returns current nightmare instance
180
- this.helpers['Nightmare'].browser;
181
- ```
182
-
183
- This way you can call [native Nightmare commands](https://github.com/segmentio/nightmare#interact-with-the-page).
184
-
185
- It is important to understand that Nightmare executes JavaScript on client and on server side.
186
- If you need to find an element you should search for it using client side script, but if you want
187
- to do an assertion you should return a data to server side.
188
-
189
- Nightmare provides `evaluate` method to execute client-side JavaScript. CodeceptJS registers `codeceptjs`
190
- object globally on client side with `findElement` and `findElements` methods in it. They return IDs of matched elements
191
- so you can access them in next calls to `evaluate`:
192
-
193
- ```js
194
- // inside a custom helper class
195
- async seeAttributeContains(locator, attribute, expectedValue) {
196
- // let's use chai assertion library
197
- const assert = require('chai').assert;
198
- // get nightmare instance
199
- const browser = this.helpers['Nightmare'].browser;
200
- // find an element by CSS or XPath:
201
- const els = await this.helpers['Nightmare']._locate(locator);
202
- // we received an array with IDs of matched elements
203
- // now let's execute client-side script to get attribute for the first element
204
- const attributeValue = await browser.evaluate(function(el, attribute) {
205
- // this is executed inside a web page!
206
- return codeceptjs.fetchElement(el).getAttribute(attribute);
207
- }, els[0], attribute); // function + its params
208
-
209
- // get attribute value and back to server side
210
- // execute an assertion
211
- assert.include(attributeValue, expectedValue);
212
- }
213
- ```
214
-
215
- It can be used in tests like:
216
-
217
- ```js
218
- I.seeAttributeContains('#main img', 'src', '/cat.jpg');
219
- ```
220
-
221
- This sample assertion used `_locate` helper method which searched for elements
222
- by CSS/XPath or a strict locator. Then `browser.evaluate` method was called to
223
- use locate found elements on a page and return attribute from the first of them.