@hs-web-team/eslint-config-node 5.2.0 → 5.3.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.
@@ -20,6 +20,10 @@ let currentOutline = null;
20
20
  /** @type {string | null} */
21
21
  let rateLimited429Outline = null;
22
22
 
23
+ // URLs whose path doesn't end in a media/download extension; skips media that scripts fetch (best-effort).
24
+ const NOT_MEDIA_OR_DOWNLOAD_URL =
25
+ /^(?![^?#]*\.(?:mp3|m4a|aac|wav|ogg|oga|opus|flac|mp4|m4v|mov|webm|mkv|m3u8|mpd|ts|m4s|pdf|zip)(?:[?#]|$))/i;
26
+
23
27
  // cy.state('runnable') is an internal API
24
28
  const currentRunnable = () => cy.state('runnable');
25
29
 
@@ -41,11 +45,15 @@ const disableRetriesForCurrentTest = () => {
41
45
  beforeEach(() => {
42
46
  rateLimit429Hit = null; // to ensure each scenario starts clean, in case a previous afterEach was skipped
43
47
 
44
- // Observe every response (middleware:true never modifies). Genuine Cloudflare 429s
48
+ // Observe responses (middleware:true never modifies). Genuine Cloudflare 429s
45
49
  // carry a cf-ray header; third-party 429s (Google c2dm, pixels, etc.) don't, so ignore
46
50
  // those — otherwise we'd wrongly disable retries / skip an outline. Gate on the header,
47
51
  // not the host, since the suite may hit several Cloudflare-fronted hosts.
48
- cy.intercept({ url: '**/*', middleware: true }, req => {
52
+ //
53
+ // Only document/fetch/xhr: Cypress sends each matched response body to the driver over CDP,
54
+ // and large media bodies overflow Chrome's 100 MB buffer and hang the run. A Cloudflare 429
55
+ // blocks the whole IP, so page loads and API calls still see it.
56
+ cy.intercept({ url: NOT_MEDIA_OR_DOWNLOAD_URL, resourceType: /^(document|fetch|xhr)$/, middleware: true }, req => {
49
57
  req.on('response', res => {
50
58
  const ray = res.headers['cf-ray'];
51
59
  if (res.statusCode === 429 && ray) {
@@ -131,6 +131,11 @@ IP block, so a retry can't pass — it just burns the limited request budget. Th
131
131
  Detection is gated on Cloudflare's `cf-ray` response header, so unrelated third-party 429s
132
132
  (pixels, analytics, etc.) don't trigger it.
133
133
 
134
+ The handler only watches `document`, `fetch` and `xhr` responses, and skips URLs ending in a
135
+ media or download extension (`.mp3`, `.mp4`, `.m3u8`, `.pdf`, …). Cypress sends every watched
136
+ response body to the driver, and large media can overflow Chrome's 100 MB DevTools buffer and
137
+ hang the run. A Cloudflare 429 blocks the whole IP, so page loads and API calls still catch it.
138
+
134
139
  ### Enabling it
135
140
 
136
141
  Add **one file inside your `stepDefinitions` glob** (commonly
@@ -155,7 +160,7 @@ dependency your suite satisfies.
155
160
 
156
161
  Real Cloudflare 429s are intermittent, so to confirm the handler fires, force one in a
157
162
  throwaway/smoke spec with a **dynamic-reply** intercept — point it at a request the page
158
- actually makes (a browser `fetch`/XHR, not `cy.request`):
163
+ actually makes (a page load or browser `fetch`/XHR, not `cy.request` or a static asset):
159
164
 
160
165
  ```js
161
166
  cy.intercept('GET', '**/your-endpoint', req =>
@@ -163,7 +168,7 @@ cy.intercept('GET', '**/your-endpoint', req =>
163
168
  );
164
169
  ```
165
170
 
166
- The handler's `**/*` middleware intercept runs first and observes the response, so the test
171
+ The handler's middleware intercept runs first and observes the response, so the test
167
172
  fails once (no retry), carries the `[RATE-LIMIT-429]` marker, and — in a Scenario Outline —
168
173
  the remaining examples are skipped. Use a dynamic `req.reply(...)`, not a static stub object:
169
174
  a static stub doesn't reliably drive the response lifecycle the middleware observes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hs-web-team/eslint-config-node",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "description": "HubSpot Marketing WebTeam shared configurations for ESLint, Prettier, Stylelint, and Cypress",
5
5
  "files": [
6
6
  ".prettierrc.json",
@@ -110,36 +110,19 @@
110
110
  "prettier": "3.9.6",
111
111
  "prettier-plugin-gherkin": "4.0.0",
112
112
  "strip-json-comments": "5.0.3",
113
+ "stylelint": "^17.1.1",
114
+ "stylelint-config-standard": "^40.0.0",
115
+ "stylelint-config-standard-scss": "^17.0.0",
116
+ "stylelint-declaration-strict-value": "^1.11.1",
113
117
  "typescript-eslint": "8.68.0"
114
118
  },
115
119
  "peerDependencies": {
116
120
  "@badeball/cypress-cucumber-preprocessor": "^24.0.1",
117
- "cypress": "^15.21.0",
118
- "stylelint": "^17.1.1",
119
- "stylelint-config-standard": "^40.0.0",
120
- "stylelint-config-standard-scss": "^17.0.0",
121
- "stylelint-declaration-strict-value": "^1.11.1"
121
+ "cypress": "^15.21.0"
122
122
  },
123
123
  "peerDependenciesMeta": {
124
- "stylelint": {
125
- "optional": true
126
- },
127
- "stylelint-config-standard": {
128
- "optional": true
129
- },
130
- "stylelint-config-standard-scss": {
131
- "optional": true
132
- },
133
- "stylelint-declaration-strict-value": {
134
- "optional": true
135
- },
136
124
  "cypress": {
137
125
  "optional": true
138
126
  }
139
- },
140
- "devDependencies": {
141
- "stylelint": "17.15.0",
142
- "stylelint-config-standard-scss": "17.0.0",
143
- "stylelint-declaration-strict-value": "1.12.1"
144
127
  }
145
128
  }