@hs-web-team/eslint-config-node 3.2.0-next.5 → 3.2.0-next.7
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/CLAUDE.md +2 -1
- package/README.md +3 -33
- package/cypress.config.cjs +1 -0
- package/cypress.config.d.ts +18 -0
- package/examples/cypress-usage.md +125 -245
- package/package.json +12 -2
- package/cypress.config.ts +0 -120
package/CLAUDE.md
CHANGED
|
@@ -94,6 +94,7 @@ When testing changes to this package in downstream projects, you'll typically:
|
|
|
94
94
|
- Uses **esbuild** preprocessor for fast bundling (much faster than webpack)
|
|
95
95
|
- Includes Cucumber preprocessor setup with native esbuild support
|
|
96
96
|
- Native TypeScript support via esbuild (no additional loader needed)
|
|
97
|
+
- `@badeball/cypress-cucumber-preprocessor`, `@bahmutov/cypress-esbuild-preprocessor`, `esbuild`, and `js-yaml` are all bundled — consumers only need to install `cypress`
|
|
97
98
|
- Spec pattern: `cypress/e2e/*.cy.js`
|
|
98
99
|
- Exported utilities:
|
|
99
100
|
- `config`: Main Cypress configuration object
|
|
@@ -111,7 +112,7 @@ When testing changes to this package in downstream projects, you'll typically:
|
|
|
111
112
|
- Browser export (`./browser`): `browser.js` - Browser/React ESLint configuration
|
|
112
113
|
- Prettier export (`./.prettierrc.json`): `.prettierrc.json` - Prettier configuration
|
|
113
114
|
- Stylelint export (`./.stylelintrc.json`): `.stylelintrc.json` - Stylelint configuration
|
|
114
|
-
- Cypress export (`./cypress.config`): `cypress.config.cjs`
|
|
115
|
+
- Cypress export (`./cypress.config`): `cypress.config.cjs` (runtime), `cypress.config.d.ts` (types)
|
|
115
116
|
- **Binary command**: `add-prettier` maps to `bin/add-prettier-scripts.js`
|
|
116
117
|
|
|
117
118
|
### Migration Context
|
package/README.md
CHANGED
|
@@ -115,43 +115,13 @@ For detailed Stylelint configuration documentation, see [examples/stylelint-usag
|
|
|
115
115
|
|
|
116
116
|
This package provides shared Cypress configuration for E2E testing.
|
|
117
117
|
|
|
118
|
-
1. Install
|
|
118
|
+
1. Install Cypress
|
|
119
119
|
|
|
120
120
|
```sh
|
|
121
|
-
npm i -D cypress
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
2. Create `cypress.config.js` in project root
|
|
125
|
-
|
|
126
|
-
```javascript
|
|
127
|
-
const { defineConfig } = require('cypress');
|
|
128
|
-
const { config, envs, getBaseUrls } = require('@hs-web-team/eslint-config-node/cypress.config');
|
|
129
|
-
|
|
130
|
-
module.exports = defineConfig({
|
|
131
|
-
...config,
|
|
132
|
-
e2e: {
|
|
133
|
-
...config.e2e,
|
|
134
|
-
baseUrl: 'http://localhost:3000',
|
|
135
|
-
},
|
|
136
|
-
env: {
|
|
137
|
-
...envs,
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
3. Add scripts to package.json
|
|
143
|
-
|
|
144
|
-
```json
|
|
145
|
-
{
|
|
146
|
-
"scripts": {
|
|
147
|
-
"cypress:open": "cypress open",
|
|
148
|
-
"cypress:run": "cypress run",
|
|
149
|
-
"test:e2e": "cypress run"
|
|
150
|
-
}
|
|
151
|
-
}
|
|
121
|
+
npm i -D cypress@15
|
|
152
122
|
```
|
|
153
123
|
|
|
154
|
-
For detailed Cypress configuration
|
|
124
|
+
For detailed Cypress configuration and migration documentation, see [examples/cypress-usage.md](./examples/cypress-usage.md).
|
|
155
125
|
|
|
156
126
|
## Where to use it
|
|
157
127
|
|
package/cypress.config.cjs
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="cypress" />
|
|
2
|
+
|
|
3
|
+
export declare const envs: {
|
|
4
|
+
currentEnv: string;
|
|
5
|
+
DEV: string;
|
|
6
|
+
QA: string;
|
|
7
|
+
PROD: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export declare const config: Cypress.ConfigOptions;
|
|
11
|
+
|
|
12
|
+
export declare function setupNodeEvents(
|
|
13
|
+
on: Cypress.PluginEvents,
|
|
14
|
+
config: Cypress.PluginConfigOptions
|
|
15
|
+
): Promise<Cypress.PluginConfigOptions>;
|
|
16
|
+
|
|
17
|
+
export declare function getDevBaseUrl(): string | null;
|
|
18
|
+
export declare function getBaseUrls(): Record<string, string | null> | null;
|
|
@@ -4,16 +4,10 @@ This package provides a shared Cypress configuration for E2E testing in HubSpot
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
For full setup instructions, see the [Cypress Framework Setup](https://git.hubteam.com/pages/MarketingWebTeam/webteam-docs/docs/developers/coding-on-the-web-team/software-testing/cypress-framework-setup/) guide.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
2. If using TypeScript:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install --save-dev typescript @types/node
|
|
10
|
+
npm i -D cypress@15
|
|
17
11
|
```
|
|
18
12
|
|
|
19
13
|
## Usage
|
|
@@ -24,18 +18,13 @@ Create a `cypress.config.js` file in your project root:
|
|
|
24
18
|
|
|
25
19
|
```javascript
|
|
26
20
|
const { defineConfig } = require('cypress');
|
|
27
|
-
const { config
|
|
21
|
+
const { config } = require('@hs-web-team/eslint-config-node/cypress.config');
|
|
28
22
|
|
|
29
23
|
module.exports = defineConfig({
|
|
30
24
|
...config,
|
|
31
25
|
e2e: {
|
|
32
26
|
...config.e2e,
|
|
33
|
-
baseUrl: 'http://localhost:3000',
|
|
34
|
-
// Add custom e2e options here
|
|
35
|
-
},
|
|
36
|
-
env: {
|
|
37
|
-
...envs,
|
|
38
|
-
// Add custom environment variables
|
|
27
|
+
baseUrl: 'http://localhost:3000',
|
|
39
28
|
},
|
|
40
29
|
});
|
|
41
30
|
```
|
|
@@ -54,7 +43,7 @@ module.exports = defineConfig({
|
|
|
54
43
|
...config,
|
|
55
44
|
e2e: {
|
|
56
45
|
...config.e2e,
|
|
57
|
-
baseUrl: baseUrls.qa
|
|
46
|
+
baseUrl: baseUrls.qa,
|
|
58
47
|
},
|
|
59
48
|
env: {
|
|
60
49
|
...envs,
|
|
@@ -67,173 +56,84 @@ module.exports = defineConfig({
|
|
|
67
56
|
|
|
68
57
|
### Core Configuration
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- **
|
|
73
|
-
- **
|
|
74
|
-
- Default command timeout: 20 seconds
|
|
75
|
-
- Page load timeout: 20 seconds
|
|
76
|
-
- Response timeout: 20 seconds
|
|
77
|
-
- **Test Settings**:
|
|
78
|
-
- Port: 3500
|
|
79
|
-
- Viewport: 1920x1080
|
|
80
|
-
- Tests kept in memory: 0 (prevents memory issues)
|
|
81
|
-
- **Retries**:
|
|
82
|
-
- Run mode: 1 retry
|
|
83
|
-
- Open mode: 0 retries
|
|
84
|
-
- **Screenshots**: Enabled on failure
|
|
59
|
+
- **Chrome Web Security**: Disabled for cross-origin testing
|
|
60
|
+
- **Timeouts**: 20s for default command, page load, and response (Cypress default is 4s)
|
|
61
|
+
- **Viewport**: 1920x1080
|
|
62
|
+
- **Retries**: 1 in run mode, 0 in open mode
|
|
85
63
|
- **Video**: Disabled by default
|
|
86
|
-
- **
|
|
64
|
+
- **Tests kept in memory**: 0 (prevents memory issues)
|
|
87
65
|
|
|
88
66
|
### E2E Configuration
|
|
89
67
|
|
|
90
|
-
- **Spec
|
|
91
|
-
- **Cucumber
|
|
92
|
-
- **TypeScript
|
|
93
|
-
- **esbuild Preprocessor**: Fast bundling for `.feature` files, TypeScript, and JavaScript
|
|
68
|
+
- **Spec pattern**: `cypress/e2e/*.cy.js`
|
|
69
|
+
- **Cucumber support**: Includes Cucumber preprocessor setup with esbuild
|
|
70
|
+
- **TypeScript support**: Native via esbuild, no additional loader needed
|
|
94
71
|
|
|
95
|
-
###
|
|
72
|
+
### Exports
|
|
96
73
|
|
|
97
|
-
|
|
74
|
+
| Export | Description |
|
|
75
|
+
|--------|-------------|
|
|
76
|
+
| `config` | Main Cypress configuration object |
|
|
77
|
+
| `envs` | Environment constants (`DEV`, `QA`, `PROD`, `currentEnv`) |
|
|
78
|
+
| `setupNodeEvents` | The `setupNodeEvents` function (for custom extension) |
|
|
79
|
+
| `getDevBaseUrl()` | Reads `baseUrl` from the DEV portal in `hubspot.config.yml` |
|
|
80
|
+
| `getBaseUrls()` | Reads URLs for all environments from `.ci/config.yml` |
|
|
98
81
|
|
|
99
82
|
#### `envs`
|
|
100
|
-
|
|
83
|
+
|
|
101
84
|
```javascript
|
|
102
|
-
|
|
103
|
-
currentEnv: 'qa',
|
|
85
|
+
{
|
|
86
|
+
currentEnv: 'qa',
|
|
104
87
|
DEV: 'DEV',
|
|
105
88
|
QA: 'qa',
|
|
106
89
|
PROD: 'prod',
|
|
107
|
-
}
|
|
90
|
+
}
|
|
108
91
|
```
|
|
109
92
|
|
|
110
93
|
#### `getDevBaseUrl()`
|
|
111
|
-
Retrieves the `baseUrl` from the `DEV` portal in `hubspot.config.yml`:
|
|
112
94
|
|
|
113
|
-
|
|
114
|
-
const devUrl = getDevBaseUrl(); // Returns baseUrl or null
|
|
115
|
-
```
|
|
95
|
+
Returns the `baseUrl` from the `DEV` portal in `hubspot.config.yml`, or `null` if not found.
|
|
116
96
|
|
|
117
|
-
**Requirements**:
|
|
118
|
-
- Project must have a `hubspot.config.yml` file
|
|
119
|
-
- DEV portal must have a `baseUrl` property configured
|
|
97
|
+
**Requirements**: `hubspot.config.yml` must exist and the DEV portal must have a `baseUrl` property.
|
|
120
98
|
|
|
121
99
|
#### `getBaseUrls()`
|
|
122
|
-
|
|
100
|
+
|
|
101
|
+
Returns base URLs for all environments:
|
|
123
102
|
|
|
124
103
|
```javascript
|
|
125
|
-
const urls = getBaseUrls();
|
|
126
104
|
// Returns: { DEV: '...', qa: '...', prod: '...' }
|
|
127
105
|
```
|
|
128
106
|
|
|
129
|
-
|
|
130
|
-
- `.ci/config.yml` file with `regression.e2eTestEnvironment` configuration
|
|
131
|
-
- Format:
|
|
132
|
-
```yaml
|
|
133
|
-
regression:
|
|
134
|
-
e2eTestEnvironment:
|
|
135
|
-
- name: qa
|
|
136
|
-
url: https://qa.example.com
|
|
137
|
-
- name: prod
|
|
138
|
-
url: https://prod.example.com
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Project Structure
|
|
142
|
-
|
|
143
|
-
### Recommended Folder Structure
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
project-root/
|
|
147
|
-
├── cypress/
|
|
148
|
-
│ ├── e2e/
|
|
149
|
-
│ │ ├── login.cy.js
|
|
150
|
-
│ │ └── homepage.cy.js
|
|
151
|
-
│ ├── fixtures/
|
|
152
|
-
│ │ └── users.json
|
|
153
|
-
│ ├── support/
|
|
154
|
-
│ │ ├── commands.js
|
|
155
|
-
│ │ └── e2e.js
|
|
156
|
-
│ └── downloads/
|
|
157
|
-
├── cypress.config.js
|
|
158
|
-
└── package.json
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### For Cucumber/BDD Testing
|
|
107
|
+
The `DEV` key comes from `getDevBaseUrl()`. The `qa` and `prod` keys come from `.ci/config.yml`:
|
|
162
108
|
|
|
109
|
+
```yaml
|
|
110
|
+
regression:
|
|
111
|
+
e2eTestEnvironment:
|
|
112
|
+
- name: qa
|
|
113
|
+
url: https://qa.example.com
|
|
114
|
+
- name: prod
|
|
115
|
+
url: https://prod.example.com
|
|
163
116
|
```
|
|
164
|
-
project-root/
|
|
165
|
-
├── cypress/
|
|
166
|
-
│ ├── e2e/
|
|
167
|
-
│ │ └── features/
|
|
168
|
-
│ │ ├── login.feature
|
|
169
|
-
│ │ └── homepage.feature
|
|
170
|
-
│ ├── support/
|
|
171
|
-
│ │ ├── step_definitions/
|
|
172
|
-
│ │ │ ├── login.ts
|
|
173
|
-
│ │ │ └── homepage.ts
|
|
174
|
-
│ │ └── e2e.ts
|
|
175
|
-
└── cypress.config.js
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Add Scripts to package.json
|
|
179
|
-
|
|
180
|
-
Add Cypress scripts to your `package.json`:
|
|
181
|
-
|
|
182
|
-
```json
|
|
183
|
-
{
|
|
184
|
-
"scripts": {
|
|
185
|
-
"cypress:open": "cypress open",
|
|
186
|
-
"cypress:run": "cypress run",
|
|
187
|
-
"cypress:run:chrome": "cypress run --browser chrome",
|
|
188
|
-
"cypress:run:headed": "cypress run --headed",
|
|
189
|
-
"test:e2e": "cypress run"
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
Then run:
|
|
195
|
-
- `npm run cypress:open` - Open Cypress Test Runner (interactive)
|
|
196
|
-
- `npm run cypress:run` - Run all tests headlessly
|
|
197
|
-
- `npm run test:e2e` - Run E2E tests (alias for cypress:run)
|
|
198
117
|
|
|
199
118
|
## Customizing Configuration
|
|
200
119
|
|
|
201
|
-
###
|
|
120
|
+
### Add Custom setupNodeEvents
|
|
202
121
|
|
|
203
|
-
|
|
204
|
-
const { defineConfig } = require('cypress');
|
|
205
|
-
const { config } = require('@hs-web-team/eslint-config-node/cypress.config');
|
|
122
|
+
`setupNodeEvents` is embedded in `config.e2e`. If you override it without calling the package's version, you'll lose the Cucumber preprocessor and esbuild setup.
|
|
206
123
|
|
|
207
|
-
|
|
208
|
-
...config,
|
|
209
|
-
// Override specific values
|
|
210
|
-
defaultCommandTimeout: 30000,
|
|
211
|
-
viewportWidth: 1280,
|
|
212
|
-
viewportHeight: 720,
|
|
213
|
-
video: true, // Enable video recording
|
|
214
|
-
e2e: {
|
|
215
|
-
...config.e2e,
|
|
216
|
-
baseUrl: 'http://localhost:8080',
|
|
217
|
-
specPattern: 'cypress/integration/**/*.spec.js',
|
|
218
|
-
},
|
|
219
|
-
});
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Add Custom setupNodeEvents
|
|
124
|
+
Import `setupNodeEvents` directly and call it first:
|
|
223
125
|
|
|
224
126
|
```javascript
|
|
225
127
|
const { defineConfig } = require('cypress');
|
|
226
|
-
const { config } = require('@hs-web-team/eslint-config-node/cypress.config');
|
|
128
|
+
const { config, setupNodeEvents: wtSetupNodeEvents } = require('@hs-web-team/eslint-config-node/cypress.config');
|
|
227
129
|
|
|
228
130
|
module.exports = defineConfig({
|
|
229
131
|
...config,
|
|
230
132
|
e2e: {
|
|
231
133
|
...config.e2e,
|
|
232
|
-
async setupNodeEvents(on,
|
|
233
|
-
|
|
234
|
-
const updatedConfig = await config.e2e.setupNodeEvents(on, cypressConfig);
|
|
134
|
+
async setupNodeEvents(on, cfg) {
|
|
135
|
+
await wtSetupNodeEvents(on, cfg);
|
|
235
136
|
|
|
236
|
-
// Add your custom tasks/events
|
|
237
137
|
on('task', {
|
|
238
138
|
log(message) {
|
|
239
139
|
console.log(message);
|
|
@@ -241,137 +141,117 @@ module.exports = defineConfig({
|
|
|
241
141
|
},
|
|
242
142
|
});
|
|
243
143
|
|
|
244
|
-
return
|
|
144
|
+
return cfg;
|
|
245
145
|
},
|
|
246
146
|
},
|
|
247
147
|
});
|
|
248
148
|
```
|
|
249
149
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
### GitHub Actions Example
|
|
150
|
+
If you don't need custom node events, omit `setupNodeEvents` entirely and just spread `...config.e2e`.
|
|
253
151
|
|
|
254
|
-
|
|
255
|
-
name: E2E Tests
|
|
256
|
-
on: [push, pull_request]
|
|
257
|
-
|
|
258
|
-
jobs:
|
|
259
|
-
cypress-run:
|
|
260
|
-
runs-on: ubuntu-latest
|
|
261
|
-
steps:
|
|
262
|
-
- name: Checkout
|
|
263
|
-
uses: actions/checkout@v4
|
|
264
|
-
|
|
265
|
-
- name: Setup Node
|
|
266
|
-
uses: actions/setup-node@v4
|
|
267
|
-
with:
|
|
268
|
-
node-version: 22
|
|
269
|
-
|
|
270
|
-
- name: Install dependencies
|
|
271
|
-
run: npm ci
|
|
272
|
-
|
|
273
|
-
- name: Run Cypress tests
|
|
274
|
-
uses: cypress-io/github-action@v6
|
|
275
|
-
with:
|
|
276
|
-
start: npm start
|
|
277
|
-
wait-on: 'http://localhost:3000'
|
|
278
|
-
```
|
|
152
|
+
## Migrating from `@hs-web-team/eslint-config-browser`
|
|
279
153
|
|
|
280
|
-
|
|
154
|
+
### 1. Update the import
|
|
281
155
|
|
|
282
|
-
|
|
156
|
+
**JavaScript:**
|
|
157
|
+
```javascript
|
|
158
|
+
// Before
|
|
159
|
+
const { getDevBaseUrl, getBaseUrls, config, envs } = require('@hs-web-team/eslint-config-browser/cypress.config.js');
|
|
283
160
|
|
|
284
|
-
|
|
285
|
-
{
|
|
286
|
-
"compilerOptions": {
|
|
287
|
-
"target": "ES2021",
|
|
288
|
-
"lib": ["ES2021", "DOM"],
|
|
289
|
-
"types": ["cypress", "node"],
|
|
290
|
-
"moduleResolution": "node",
|
|
291
|
-
"esModuleInterop": true,
|
|
292
|
-
"skipLibCheck": true,
|
|
293
|
-
"strict": true
|
|
294
|
-
},
|
|
295
|
-
"include": ["cypress/**/*.ts"],
|
|
296
|
-
"exclude": ["node_modules"]
|
|
297
|
-
}
|
|
161
|
+
// After
|
|
162
|
+
const { getDevBaseUrl, getBaseUrls, config, envs } = require('@hs-web-team/eslint-config-node/cypress.config');
|
|
298
163
|
```
|
|
299
164
|
|
|
300
|
-
|
|
165
|
+
**TypeScript (module format stays the same — ESM `import`/`export default` still works):**
|
|
166
|
+
```typescript
|
|
167
|
+
// Before
|
|
168
|
+
import { getDevBaseUrl, getBaseUrls, config, envs } from '@hs-web-team/eslint-config-browser/cypress.config.js';
|
|
301
169
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
1. Install dependencies:
|
|
305
|
-
```bash
|
|
306
|
-
npm install --save-dev @badeball/cypress-cucumber-preprocessor
|
|
170
|
+
// After
|
|
171
|
+
import { getDevBaseUrl, getBaseUrls, envs, config as wtConfig } from '@hs-web-team/eslint-config-node/cypress.config';
|
|
307
172
|
```
|
|
308
173
|
|
|
309
|
-
2.
|
|
310
|
-
```json
|
|
311
|
-
{
|
|
312
|
-
"stepDefinitions": "cypress/support/step_definitions/**/*.{js,ts}",
|
|
313
|
-
"json": {
|
|
314
|
-
"enabled": true,
|
|
315
|
-
"output": "cypress/results/cucumber-report.json"
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
3. Write feature files in `cypress/e2e/features/`:
|
|
321
|
-
```gherkin
|
|
322
|
-
Feature: Login
|
|
323
|
-
|
|
324
|
-
Scenario: User can login successfully
|
|
325
|
-
Given I visit the login page
|
|
326
|
-
When I enter valid credentials
|
|
327
|
-
Then I should see the dashboard
|
|
328
|
-
```
|
|
174
|
+
### 2. Remove manual `setupNodeEvents`
|
|
329
175
|
|
|
330
|
-
|
|
176
|
+
Cucumber and esbuild are bundled into `config.e2e.setupNodeEvents`. Remove your manual `setupNodeEvents` function entirely and spread `...config.e2e` to inherit it automatically.
|
|
331
177
|
|
|
332
|
-
|
|
178
|
+
If you need to add custom tasks on top, see [Add Custom setupNodeEvents](#add-custom-setupnodeevents).
|
|
333
179
|
|
|
334
|
-
|
|
335
|
-
- Support for latest React, Angular, Next.js, Svelte, and Vite versions
|
|
336
|
-
- Seamless handling of Chrome's document.domain deprecation
|
|
337
|
-
- Upgraded Electron with Chromium 130+ for enhanced stability
|
|
338
|
-
- Better `cy.origin()` support for cross-subdomain navigation
|
|
180
|
+
### 3. Update the config structure
|
|
339
181
|
|
|
340
|
-
|
|
182
|
+
The old pattern built the full `e2e` object from scratch — repeating settings already in the bundle — then assigned it:
|
|
341
183
|
|
|
342
|
-
|
|
184
|
+
```javascript
|
|
185
|
+
const customConfig = { ...config };
|
|
186
|
+
const e2e = {
|
|
187
|
+
specPattern: 'cypress/e2e/**/*.feature',
|
|
188
|
+
baseUrl,
|
|
189
|
+
setupNodeEvents, // manual webpack + cucumber setup
|
|
190
|
+
defaultCommandTimeout: 20000, // already in bundle
|
|
191
|
+
retries: { runMode: 1, openMode: 0 }, // already in bundle
|
|
192
|
+
// ...
|
|
193
|
+
};
|
|
194
|
+
customConfig.e2e = e2e;
|
|
195
|
+
module.exports = defineConfig(customConfig);
|
|
196
|
+
```
|
|
343
197
|
|
|
344
|
-
The
|
|
198
|
+
The new pattern spreads `...config.e2e` to inherit bundled settings (including `setupNodeEvents`) and only adds project-specific overrides:
|
|
345
199
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
200
|
+
**JavaScript:**
|
|
201
|
+
```javascript
|
|
202
|
+
module.exports = defineConfig({
|
|
203
|
+
...config,
|
|
204
|
+
e2e: {
|
|
205
|
+
...config.e2e,
|
|
206
|
+
specPattern: 'cypress/e2e/**/*.feature',
|
|
207
|
+
baseUrl,
|
|
208
|
+
supportFile: 'cypress/support/e2e.js',
|
|
209
|
+
reporter: 'mochawesome',
|
|
210
|
+
reporterOptions: {
|
|
211
|
+
reportDir: 'cypress/results',
|
|
212
|
+
overwrite: false,
|
|
213
|
+
html: true,
|
|
214
|
+
json: true,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
```
|
|
350
219
|
|
|
351
|
-
|
|
220
|
+
**TypeScript:**
|
|
221
|
+
```typescript
|
|
222
|
+
export default defineConfig({
|
|
223
|
+
e2e: {
|
|
224
|
+
...wtConfig.e2e,
|
|
225
|
+
specPattern: 'cypress/e2e/**/*.feature',
|
|
226
|
+
baseUrl,
|
|
227
|
+
supportFile: 'cypress/support/e2e.ts',
|
|
228
|
+
reporter: 'mochawesome',
|
|
229
|
+
reporterOptions: {
|
|
230
|
+
reportDir: 'cypress/results',
|
|
231
|
+
overwrite: false,
|
|
232
|
+
html: true,
|
|
233
|
+
json: true,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
blockHosts: '*.google-analytics.com',
|
|
237
|
+
});
|
|
238
|
+
```
|
|
352
239
|
|
|
353
|
-
###
|
|
240
|
+
### 4. Keep project-specific settings not in the bundle
|
|
354
241
|
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
npm install --save-dev cypress @badeball/cypress-cucumber-preprocessor esbuild js-yaml
|
|
358
|
-
```
|
|
242
|
+
These are not included in the bundle and must be carried over manually if your project uses them:
|
|
359
243
|
|
|
360
|
-
|
|
244
|
+
- `reporter` and `reporterOptions` (e.g. mochawesome)
|
|
245
|
+
- `supportFile`
|
|
246
|
+
- `blockHosts`
|
|
247
|
+
- `fixturesFolder`, `screenshotsFolder`, `videosFolder`
|
|
248
|
+
- `testIsolation`
|
|
249
|
+
- `specPattern` (if using `.feature` files — bundle default is `cypress/e2e/*.cy.js`)
|
|
361
250
|
|
|
362
|
-
|
|
363
|
-
```bash
|
|
364
|
-
npm install --save-dev esbuild
|
|
365
|
-
```
|
|
251
|
+
## Troubleshooting
|
|
366
252
|
|
|
367
253
|
### Environment Configuration Not Loading
|
|
368
254
|
|
|
369
255
|
Ensure your project has the required configuration files:
|
|
370
256
|
- `hubspot.config.yml` for HubSpot projects
|
|
371
257
|
- `.ci/config.yml` for multi-environment setups
|
|
372
|
-
|
|
373
|
-
### Memory Issues
|
|
374
|
-
|
|
375
|
-
The configuration sets `numTestsKeptInMemory: 0` to prevent memory issues. If you still experience problems, consider:
|
|
376
|
-
- Running tests in smaller batches
|
|
377
|
-
- Increasing Node.js memory: `NODE_OPTIONS=--max_old_space_size=4096 cypress run`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hs-web-team/eslint-config-node",
|
|
3
|
-
"version": "3.2.0-next.
|
|
3
|
+
"version": "3.2.0-next.7",
|
|
4
4
|
"description": "HubSpot Marketing WebTeam shared configurations for ESLint, Prettier, Stylelint, and Cypress",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,17 @@
|
|
|
9
9
|
"./browser": "./browser.js",
|
|
10
10
|
"./.prettierrc.json": "./.prettierrc.json",
|
|
11
11
|
"./.stylelintrc.json": "./.stylelintrc.json",
|
|
12
|
-
"./cypress.config":
|
|
12
|
+
"./cypress.config": {
|
|
13
|
+
"types": "./cypress.config.d.ts",
|
|
14
|
+
"require": "./cypress.config.cjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"typesVersions": {
|
|
18
|
+
"*": {
|
|
19
|
+
"cypress.config": [
|
|
20
|
+
"./cypress.config.d.ts"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
13
23
|
},
|
|
14
24
|
"scripts": {
|
|
15
25
|
"lint": "npx eslint -c ./index.js *.js --fix",
|
package/cypress.config.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import yaml from 'js-yaml';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import createBundler from '@bahmutov/cypress-esbuild-preprocessor';
|
|
5
|
-
import { addCucumberPreprocessorPlugin } from '@badeball/cypress-cucumber-preprocessor';
|
|
6
|
-
import { createEsbuildPlugin } from '@badeball/cypress-cucumber-preprocessor/esbuild';
|
|
7
|
-
|
|
8
|
-
const DEV = 'DEV';
|
|
9
|
-
const QA = 'qa';
|
|
10
|
-
const PROD = 'prod';
|
|
11
|
-
const currentEnv = QA;
|
|
12
|
-
|
|
13
|
-
export const envs = {
|
|
14
|
-
currentEnv,
|
|
15
|
-
DEV,
|
|
16
|
-
QA,
|
|
17
|
-
PROD,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @description Recursively climbs up the filepath, until it finds what directory
|
|
22
|
-
* the directory where the hubspot.config.yml file is located.
|
|
23
|
-
*
|
|
24
|
-
* @param {string} currDir - the current working directory path to search from
|
|
25
|
-
* @returns {string} The absolute path of the project's root directory
|
|
26
|
-
*/
|
|
27
|
-
const getRootDir = (currDir: string): string => {
|
|
28
|
-
if (fs.existsSync(path.join(currDir, 'hubspot.config.yml'))) return currDir;
|
|
29
|
-
const parentDir = path.dirname(currDir);
|
|
30
|
-
if (parentDir === currDir) {
|
|
31
|
-
throw new Error('Error: Could not find the hubspot.config.yml file within the projects directories.');
|
|
32
|
-
}
|
|
33
|
-
return getRootDir(parentDir);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @returns {string|null} The `baseUrl` set for the `DEV` portal in `hubspot.config.yml`
|
|
38
|
-
* or `null` if this is not the dev environment or no such property exists.
|
|
39
|
-
*/
|
|
40
|
-
export const getDevBaseUrl = (): string | null => {
|
|
41
|
-
try {
|
|
42
|
-
global.console.log(
|
|
43
|
-
'To test a dev URL, add the `baseUrl` property to your `DEV` portal configuration in `hubspot.config.yml`',
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const root = getRootDir(__dirname);
|
|
47
|
-
const configPath = path.resolve(root, 'hubspot.config.yml');
|
|
48
|
-
const fileContents = fs.readFileSync(configPath, 'utf8');
|
|
49
|
-
const { portals } = yaml.load(fileContents) as { portals: Array<{ name: string; baseUrl?: string }> };
|
|
50
|
-
const devPortal = portals.find(portal => portal.name === 'DEV');
|
|
51
|
-
return devPortal?.baseUrl || null;
|
|
52
|
-
} catch (error) {
|
|
53
|
-
global.console.error(error);
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @description Get the baseUrls for different environments from the ci config file for local test execution.
|
|
60
|
-
* @returns {object} baseUrls - The base urls object
|
|
61
|
-
*/
|
|
62
|
-
export const getBaseUrls = (): Record<string, string | null> | null => {
|
|
63
|
-
let fileContents = '';
|
|
64
|
-
let ciConfig: { regression?: { e2eTestEnvironment?: Array<{ name: string; url: string }> } } = {};
|
|
65
|
-
const baseUrls: Record<string, string | null> = {};
|
|
66
|
-
baseUrls[envs.DEV] = getDevBaseUrl();
|
|
67
|
-
|
|
68
|
-
const fileExist = fs.existsSync('.ci/config.yml');
|
|
69
|
-
if (fileExist) {
|
|
70
|
-
fileContents = fs.readFileSync('.ci/config.yml', 'utf8');
|
|
71
|
-
ciConfig = yaml.load(fileContents) as typeof ciConfig;
|
|
72
|
-
if (ciConfig.regression?.e2eTestEnvironment && ciConfig.regression.e2eTestEnvironment.length > 0) {
|
|
73
|
-
try {
|
|
74
|
-
ciConfig.regression.e2eTestEnvironment.forEach(item => {
|
|
75
|
-
baseUrls[item.name] = item.url;
|
|
76
|
-
});
|
|
77
|
-
} catch (error) {
|
|
78
|
-
console.error('Error reading the base urls from the ci config file:', error);
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return baseUrls || null;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
async function setupNodeEvents(
|
|
87
|
-
on: Cypress.PluginEvents,
|
|
88
|
-
config: Cypress.PluginConfigOptions,
|
|
89
|
-
): Promise<Cypress.PluginConfigOptions> {
|
|
90
|
-
await addCucumberPreprocessorPlugin(on, config);
|
|
91
|
-
on(
|
|
92
|
-
'file:preprocessor',
|
|
93
|
-
createBundler({ plugins: [createEsbuildPlugin(config)] }),
|
|
94
|
-
);
|
|
95
|
-
return config;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const e2e: Cypress.EndToEndConfigOptions = {
|
|
99
|
-
specPattern: 'cypress/e2e/*.cy.js',
|
|
100
|
-
setupNodeEvents,
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const config: Cypress.ConfigOptions = {
|
|
104
|
-
chromeWebSecurity: false,
|
|
105
|
-
defaultCommandTimeout: 20000,
|
|
106
|
-
e2e,
|
|
107
|
-
numTestsKeptInMemory: 0,
|
|
108
|
-
pageLoadTimeout: 20000,
|
|
109
|
-
port: 3500,
|
|
110
|
-
responseTimeout: 20000,
|
|
111
|
-
retries: {
|
|
112
|
-
runMode: 1,
|
|
113
|
-
openMode: 0,
|
|
114
|
-
},
|
|
115
|
-
screenshotOnRunFailure: true,
|
|
116
|
-
trashAssetsBeforeRuns: true,
|
|
117
|
-
video: false,
|
|
118
|
-
viewportHeight: 1080,
|
|
119
|
-
viewportWidth: 1920,
|
|
120
|
-
};
|