cypress-plugin-grep-boxes 1.1.3 → 2.0.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.
- package/README.md +13 -6
- package/assets/cy-grep-boxes-demo.gif +0 -0
- package/cypress/e2e/2-advanced-examples/window.cy.js +9 -5
- package/cypress/support/e2e.js +1 -3
- package/index.js +293 -162
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
A companion Cypress plugin for <code>cy-grep</code> that allows user to run specific test(s) in <code>open</code> mode.
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
-

|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
13
|
- ✅ A new UI test selection within `cypress open` to filter and run only selected tests in a given spec
|
|
14
|
+
- 🚩 _NEW_ in v2.0.0: Tags are now displayed and can be clicked to filter by respective tag in `cypress open`
|
|
14
15
|
|
|
15
16
|
#### Table of Contents
|
|
16
17
|
|
|
@@ -27,6 +28,9 @@ A companion Cypress plugin for <code>cy-grep</code> that allows user to run spec
|
|
|
27
28
|
|
|
28
29
|
1. Install the following packages:
|
|
29
30
|
|
|
31
|
+
> [!NOTE]
|
|
32
|
+
> To support `cypress-plugin-grep-boxes` displaying test tags in the Cypress Test Runner, `@bahmutov/cy-grep` must be on version >= 2.1.0
|
|
33
|
+
|
|
30
34
|
```sh
|
|
31
35
|
npm install --save-dev @bahmutov/cy-grep # Dependent package for the plugin
|
|
32
36
|
npm install --save-dev cypress-plugin-grep-boxes
|
|
@@ -34,14 +38,14 @@ npm install --save-dev cypress-plugin-grep-boxes
|
|
|
34
38
|
|
|
35
39
|
2. In `cypress/support/e2e.js` (For E2E tests) and/or `cypress/support/component.js` (For Component tests),
|
|
36
40
|
|
|
41
|
+
> [!IMPORTANT]
|
|
42
|
+
> In the plugin version 2.0.0, the `e2e.js` (or `component.js`) support file import has been updated for simplicity:
|
|
43
|
+
|
|
37
44
|
```js
|
|
38
|
-
import
|
|
45
|
+
import 'cypress-plugin-grep-boxes';
|
|
39
46
|
import registerCypressGrep from '@bahmutov/cy-grep/src/support';
|
|
40
47
|
|
|
41
48
|
registerCypressGrep();
|
|
42
|
-
|
|
43
|
-
greppedTestToggle();
|
|
44
|
-
addGrepButtons();
|
|
45
49
|
```
|
|
46
50
|
|
|
47
51
|
---
|
|
@@ -64,7 +68,10 @@ addGrepButtons();
|
|
|
64
68
|
|
|
65
69
|
## ✅ Open mode
|
|
66
70
|
|
|
67
|
-
Within each spec
|
|
71
|
+
Within each spec in Cypress `open` mode:
|
|
72
|
+
|
|
73
|
+
- You can select any given number of individual test(s) and click the filter toggle located on the reporter above
|
|
74
|
+
- You can click on any available tag and run only tests in the spec with the respective tag
|
|
68
75
|
|
|
69
76
|

|
|
70
77
|
|
|
Binary file
|
|
@@ -10,12 +10,16 @@ context('Window', () => {
|
|
|
10
10
|
cy.window().should('have.property', 'top');
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
it(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
it(
|
|
14
|
+
'cy.document() - get the document object',
|
|
15
|
+
{ tags: ['@sanity', '@smoke'] },
|
|
16
|
+
() => {
|
|
17
|
+
// https://on.cypress.io/document
|
|
18
|
+
cy.document().should('have.property', 'charset').and('eq', 'UTF-8');
|
|
19
|
+
}
|
|
20
|
+
);
|
|
17
21
|
|
|
18
|
-
it('cy.title() - get the title', () => {
|
|
22
|
+
it('cy.title() - get the title', { tags: '@title' }, () => {
|
|
19
23
|
// https://on.cypress.io/title
|
|
20
24
|
cy.title().should('include', 'Kitchen Sink');
|
|
21
25
|
});
|
package/cypress/support/e2e.js
CHANGED
|
@@ -15,12 +15,10 @@
|
|
|
15
15
|
|
|
16
16
|
// Import commands.js using ES2015 syntax:
|
|
17
17
|
import './commands';
|
|
18
|
-
import
|
|
18
|
+
import '../../index';
|
|
19
19
|
import registerCypressGrep from '@bahmutov/cy-grep/src/support';
|
|
20
20
|
|
|
21
21
|
registerCypressGrep();
|
|
22
|
-
greppedTestToggle();
|
|
23
|
-
addGrepButtons();
|
|
24
22
|
|
|
25
23
|
// Alternatively you can use CommonJS syntax:
|
|
26
24
|
// require('./commands')
|
package/index.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import registerCypressGrep from '@bahmutov/cy-grep';
|
|
2
1
|
/**
|
|
3
2
|
* Adds a toggle to reporter to grep selected tests.
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
const tests = [];
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const hasToggleButton = window.top?.document.querySelector('#grepTestToggle');
|
|
12
|
-
const defaultStyles = `
|
|
7
|
+
const hasStyles = window.top?.document.querySelector('#grepTestToggleStyle');
|
|
8
|
+
const hasToggleButton = window.top?.document.querySelector('#grepTestToggle');
|
|
9
|
+
const defaultStyles = `
|
|
13
10
|
.reporter header {
|
|
14
11
|
overflow: visible;
|
|
15
12
|
z-index: 2;
|
|
@@ -68,140 +65,181 @@ export const greppedTestToggle = () => {
|
|
|
68
65
|
overflow: visible !important
|
|
69
66
|
}
|
|
70
67
|
`;
|
|
71
|
-
|
|
68
|
+
const turnOngrepTestToggleIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#afb3c7" class="bi bi-collection-play-fill" viewBox="0 0 16 16">
|
|
72
69
|
<path d="M2.5 3.5a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1zm2-2a.5.5 0 0 1 0-1h7a.5.5 0 0 1 0 1zM0 13a1.5 1.5 0 0 0 1.5 1.5h13A1.5 1.5 0 0 0 16 13V6a1.5 1.5 0 0 0-1.5-1.5h-13A1.5 1.5 0 0 0 0 6zm6.258-6.437a.5.5 0 0 1 .507.013l4 2.5a.5.5 0 0 1 0 .848l-4 2.5A.5.5 0 0 1 6 12V7a.5.5 0 0 1 .258-.437"/>
|
|
73
70
|
</svg>`;
|
|
74
71
|
|
|
75
|
-
|
|
72
|
+
const turnOffgrepTestToggleIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#afb3c7" class="bi bi-collection-play" viewBox="0 0 16 16">
|
|
76
73
|
<path d="M2 3a.5.5 0 0 0 .5.5h11a.5.5 0 0 0 0-1h-11A.5.5 0 0 0 2 3m2-2a.5.5 0 0 0 .5.5h7a.5.5 0 0 0 0-1h-7A.5.5 0 0 0 4 1m2.765 5.576A.5.5 0 0 0 6 7v5a.5.5 0 0 0 .765.424l4-2.5a.5.5 0 0 0 0-.848z"/>
|
|
77
74
|
<path d="M1.5 14.5A1.5 1.5 0 0 1 0 13V6a1.5 1.5 0 0 1 1.5-1.5h13A1.5 1.5 0 0 1 16 6v7a1.5 1.5 0 0 1-1.5 1.5zm13-1a.5.5 0 0 0 .5-.5V6a.5.5 0 0 0-.5-.5h-13A.5.5 0 0 0 1 6v7a.5.5 0 0 0 .5.5z"/>
|
|
78
75
|
</svg>`;
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
const turnOffgrepTestToggleDescription = 'Filter selected tests';
|
|
78
|
+
const turnOngrepTestToggleDescription = 'Unfilter selected tests';
|
|
82
79
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
reporterStyleEl.setAttribute('id', 'grepTestToggleStyle');
|
|
93
|
-
reporterStyleEl.innerHTML = defaultStyles;
|
|
94
|
-
reporterEl?.appendChild(reporterStyleEl);
|
|
80
|
+
// append styles
|
|
81
|
+
if (!hasStyles) {
|
|
82
|
+
let reporterEl;
|
|
83
|
+
const reporterStyleEl = document.createElement('style');
|
|
84
|
+
if (Cypress.version >= '15.0.0') {
|
|
85
|
+
reporterEl = window.top?.document.querySelector('.runnable-header');
|
|
86
|
+
} else {
|
|
87
|
+
reporterEl = window.top?.document.querySelector('#unified-reporter');
|
|
95
88
|
}
|
|
89
|
+
reporterStyleEl.setAttribute('id', 'grepTestToggleStyle');
|
|
90
|
+
reporterStyleEl.innerHTML = defaultStyles;
|
|
91
|
+
reporterEl?.appendChild(reporterStyleEl);
|
|
92
|
+
}
|
|
96
93
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
const headerToggleDiv = document.createElement('div');
|
|
107
|
-
const headerToggleSpan = document.createElement('span');
|
|
108
|
-
const headerToggleTooltip = document.createElement('span');
|
|
109
|
-
const headerToggleButton = document.createElement('button');
|
|
110
|
-
const headerToggleInput = document.createElement('input');
|
|
111
|
-
const headerToggleLabel = document.createElement('label');
|
|
112
|
-
|
|
113
|
-
headerToggleInput.setAttribute('type', 'checkbox');
|
|
114
|
-
|
|
115
|
-
headerToggleInput.setAttribute('id', 'grepTestToggle');
|
|
116
|
-
headerToggleLabel.setAttribute('for', 'grepTestToggle');
|
|
117
|
-
headerToggleLabel.setAttribute('id', 'grepTestToggleLabel');
|
|
118
|
-
headerToggleLabel.innerHTML = turnOffgrepTestToggleIcon;
|
|
119
|
-
|
|
120
|
-
headerToggleDiv.setAttribute('id', 'grepTestToggleControls');
|
|
121
|
-
headerToggleTooltip.setAttribute('id', 'grepTestToggleTooltip');
|
|
122
|
-
headerToggleTooltip.innerText = turnOffgrepTestToggleDescription;
|
|
123
|
-
headerToggleButton.setAttribute(
|
|
124
|
-
'aria-label',
|
|
125
|
-
turnOffgrepTestToggleDescription
|
|
126
|
-
);
|
|
127
|
-
headerToggleButton.setAttribute('id', 'grepTestToggleButton');
|
|
128
|
-
|
|
129
|
-
headerToggleDiv.setAttribute('class', 'controls');
|
|
130
|
-
header?.appendChild(headerToggleDiv);
|
|
131
|
-
headerToggleDiv?.appendChild(headerToggleSpan);
|
|
132
|
-
headerToggleDiv?.appendChild(headerToggleTooltip);
|
|
133
|
-
headerToggleSpan?.appendChild(headerToggleButton);
|
|
134
|
-
headerToggleButton?.appendChild(headerToggleInput);
|
|
135
|
-
headerToggleButton?.appendChild(headerToggleLabel);
|
|
94
|
+
if (!hasToggleButton) {
|
|
95
|
+
let header;
|
|
96
|
+
if (Cypress.version >= '15.0.0') {
|
|
97
|
+
// TODO: Cypress v15 GUI provides option for Cypress Studio which pushes the grep toggle button around the UI
|
|
98
|
+
// For simplicity, moving the toggle button to the spec container above the stop button
|
|
99
|
+
header = window.top?.document.querySelector('.runnable-header');
|
|
100
|
+
} else {
|
|
101
|
+
header = window.top?.document.querySelector('#unified-reporter header');
|
|
136
102
|
}
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
|
|
103
|
+
const headerToggleDiv = document.createElement('div');
|
|
104
|
+
const headerToggleSpan = document.createElement('span');
|
|
105
|
+
const headerToggleTooltip = document.createElement('span');
|
|
106
|
+
const headerToggleButton = document.createElement('button');
|
|
107
|
+
const headerToggleInput = document.createElement('input');
|
|
108
|
+
const headerToggleLabel = document.createElement('label');
|
|
109
|
+
|
|
110
|
+
headerToggleInput.setAttribute('type', 'checkbox');
|
|
111
|
+
|
|
112
|
+
headerToggleInput.setAttribute('id', 'grepTestToggle');
|
|
113
|
+
headerToggleLabel.setAttribute('for', 'grepTestToggle');
|
|
114
|
+
headerToggleLabel.setAttribute('id', 'grepTestToggleLabel');
|
|
115
|
+
headerToggleLabel.innerHTML = turnOffgrepTestToggleIcon;
|
|
116
|
+
|
|
117
|
+
headerToggleDiv.setAttribute('id', 'grepTestToggleControls');
|
|
118
|
+
headerToggleTooltip.setAttribute('id', 'grepTestToggleTooltip');
|
|
119
|
+
headerToggleTooltip.innerText = turnOffgrepTestToggleDescription;
|
|
120
|
+
headerToggleButton.setAttribute(
|
|
121
|
+
'aria-label',
|
|
122
|
+
turnOffgrepTestToggleDescription
|
|
145
123
|
);
|
|
124
|
+
headerToggleButton.setAttribute('id', 'grepTestToggleButton');
|
|
125
|
+
|
|
126
|
+
headerToggleDiv.setAttribute('class', 'controls');
|
|
127
|
+
header?.appendChild(headerToggleDiv);
|
|
128
|
+
headerToggleDiv?.appendChild(headerToggleSpan);
|
|
129
|
+
headerToggleDiv?.appendChild(headerToggleTooltip);
|
|
130
|
+
headerToggleSpan?.appendChild(headerToggleButton);
|
|
131
|
+
headerToggleButton?.appendChild(headerToggleInput);
|
|
132
|
+
headerToggleButton?.appendChild(headerToggleLabel);
|
|
133
|
+
}
|
|
146
134
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
135
|
+
const grepTestToggleElement =
|
|
136
|
+
window.top?.document.querySelector('#grepTestToggle');
|
|
137
|
+
const grepTestToggleLabelElement = window.top?.document.querySelector(
|
|
138
|
+
'[for=grepTestToggle]'
|
|
139
|
+
);
|
|
140
|
+
const grepTestToggleTooltipElement = window.top?.document.querySelector(
|
|
141
|
+
'#grepTestToggleTooltip'
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
grepTestToggleElement?.addEventListener('change', (e) => {
|
|
145
|
+
const stopBtn = window.top?.document.querySelector('.reporter .stop');
|
|
146
|
+
|
|
147
|
+
if (e.target.checked) {
|
|
148
|
+
if (stopBtn) {
|
|
149
|
+
stopBtn.click();
|
|
150
|
+
}
|
|
151
|
+
// store all checked checkbox values then send to grep in accepted format
|
|
152
|
+
const tests = [
|
|
153
|
+
...window.top?.document.querySelectorAll('.grep-test-checkbox:checked'),
|
|
154
|
+
].map((e) => e.value);
|
|
155
|
+
// store all non-checked checkbox values
|
|
156
|
+
const uncheckedTests = [
|
|
157
|
+
...window.top?.document.querySelectorAll(
|
|
158
|
+
'.grep-test-checkbox:not(:checked)'
|
|
159
|
+
),
|
|
160
|
+
].map((e) => e.value);
|
|
161
|
+
|
|
162
|
+
tests.forEach((t) => {
|
|
163
|
+
// if a checked test title begins with the grep inverted '-' symbol, remove the '-'
|
|
164
|
+
if (t[0] === '-') {
|
|
165
|
+
tests.push(t.slice(1));
|
|
166
|
+
tests.splice(
|
|
167
|
+
tests.findIndex((e) => e === t),
|
|
168
|
+
1
|
|
169
|
+
);
|
|
153
170
|
}
|
|
154
|
-
// store all checked checkbox values then send to grep in accepted format
|
|
155
|
-
const tests = [
|
|
156
|
-
...window.top?.document.querySelectorAll('.grep-test-checkbox:checked'),
|
|
157
|
-
].map((e) => e.value);
|
|
158
|
-
// store all non-checked checkbox values
|
|
159
|
-
const uncheckedTests = [
|
|
160
|
-
...window.top?.document.querySelectorAll(
|
|
161
|
-
'.grep-test-checkbox:not(:checked)'
|
|
162
|
-
),
|
|
163
|
-
].map((e) => e.value);
|
|
164
|
-
|
|
165
|
-
tests.forEach((t) => {
|
|
166
|
-
// if a checked test title begins with the grep inverted '-' symbol, remove the '-'
|
|
167
|
-
if (t[0] === '-') {
|
|
168
|
-
tests.push(t.slice(1));
|
|
169
|
-
tests.splice(
|
|
170
|
-
tests.findIndex((e) => e === t),
|
|
171
|
-
1
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
171
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
});
|
|
172
|
+
// if a non-checked test's title includes a checked test's title, invert grep for unchecked title
|
|
173
|
+
uncheckedTests.forEach((u) => {
|
|
174
|
+
if (u.includes(t)) {
|
|
175
|
+
tests.push(`-${u}`);
|
|
176
|
+
}
|
|
181
177
|
});
|
|
178
|
+
});
|
|
182
179
|
|
|
183
|
-
|
|
180
|
+
Cypress.grep(tests.join(';'));
|
|
184
181
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
182
|
+
// when checked, grep only selected tests in spec
|
|
183
|
+
grepTestToggleLabelElement.innerHTML = turnOngrepTestToggleIcon;
|
|
184
|
+
grepTestToggleTooltipElement.innerHTML = turnOngrepTestToggleDescription;
|
|
185
|
+
} else {
|
|
186
|
+
if (stopBtn) {
|
|
187
|
+
stopBtn.click();
|
|
188
|
+
}
|
|
189
|
+
// when unchecked, ungrep and show all tests in spec
|
|
190
|
+
Cypress.grep();
|
|
191
|
+
grepTestToggleLabelElement.innerHTML = turnOffgrepTestToggleIcon;
|
|
192
|
+
grepTestToggleTooltipElement.innerHTML = turnOffgrepTestToggleDescription;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Wrapping logic within isInteractive check
|
|
197
|
+
// This targets cypress open mode where user can switch specs
|
|
198
|
+
if (Cypress.config('isInteractive')) {
|
|
199
|
+
Cypress.on('window:unload', () => {
|
|
200
|
+
addTags();
|
|
201
|
+
// Store the current Cypress test runner url
|
|
202
|
+
// This is to check against any spec change in test runner while the grep filter is activated
|
|
203
|
+
// If a user does switch spec while filter is active, the filter will be reset
|
|
204
|
+
const sidebarSpecLinkPage = window.top?.document.querySelector(
|
|
205
|
+
'[data-cy="sidebar-link-specs-page"]'
|
|
206
|
+
);
|
|
207
|
+
const grepTestToggleElement =
|
|
208
|
+
window.top?.document.querySelector('#grepTestToggle');
|
|
209
|
+
|
|
210
|
+
if (
|
|
211
|
+
window.top?.document.URL !=
|
|
212
|
+
sidebarSpecLinkPage.getAttribute('data-url') &&
|
|
213
|
+
grepTestToggleElement.checked
|
|
214
|
+
) {
|
|
215
|
+
grepTestToggleElement.click();
|
|
196
216
|
}
|
|
217
|
+
|
|
218
|
+
sidebarSpecLinkPage.setAttribute('data-url', window.top?.document.URL);
|
|
197
219
|
});
|
|
198
|
-
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (Cypress.config('isInteractive')) {
|
|
223
|
+
if (
|
|
224
|
+
// if the grep test toggle is not checked, do not run tests
|
|
225
|
+
Cypress.env('disableInitialAutoRun') &&
|
|
226
|
+
window.top?.document.querySelectorAll('#grepTestToggle:checked').length ===
|
|
227
|
+
0
|
|
228
|
+
) {
|
|
229
|
+
const sidebarSpecLinkPage = window.top?.document.querySelector(
|
|
230
|
+
'[data-cy="sidebar-link-specs-page"]'
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
sidebarSpecLinkPage.setAttribute('data-url', window.top?.document.URL);
|
|
234
|
+
Cypress.runner.stop();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
199
237
|
|
|
200
238
|
/**
|
|
201
239
|
* Adds a checkbox for each suite and test for run selection.
|
|
202
240
|
*/
|
|
203
241
|
|
|
204
|
-
|
|
242
|
+
const addGrepButtons = () => {
|
|
205
243
|
const hasStyles = window.top?.document.querySelector('#grepButtonsStyle');
|
|
206
244
|
|
|
207
245
|
const grepTestsBtnClass = 'grep-tests-btn';
|
|
@@ -294,45 +332,136 @@ export const addGrepButtons = () => {
|
|
|
294
332
|
});
|
|
295
333
|
};
|
|
296
334
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
Cypress.on('window:unload', () => {
|
|
301
|
-
// Store the current Cypress test runner url
|
|
302
|
-
// This is to check against any spec change in test runner while the grep filter is activated
|
|
303
|
-
// If a user does switch spec while filter is active, the filter will be reset
|
|
304
|
-
const sidebarSpecLinkPage = window.top?.document.querySelector(
|
|
305
|
-
'[data-cy="sidebar-link-specs-page"]'
|
|
306
|
-
);
|
|
307
|
-
const grepTestToggleElement =
|
|
308
|
-
window.top?.document.querySelector('#grepTestToggle');
|
|
335
|
+
/**
|
|
336
|
+
* Adds a clickable test tag for each respective test in Cypress open mode.
|
|
337
|
+
*/
|
|
309
338
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
339
|
+
export const addTags = () => {
|
|
340
|
+
const defaultStyles = `
|
|
341
|
+
[data-attribute="test-tags"]:focus {
|
|
342
|
+
box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.9);;
|
|
343
|
+
outline: none;
|
|
344
|
+
}
|
|
345
|
+
`;
|
|
346
|
+
if (Cypress.env('specTags')) {
|
|
347
|
+
const hasStyles = window.top?.document.querySelector('#tagPillStyle');
|
|
348
|
+
|
|
349
|
+
if (!hasStyles) {
|
|
350
|
+
const runnablesStyleEl = window.top?.document.createElement('style');
|
|
351
|
+
const runnables = window.top?.document.querySelector('.runnables');
|
|
352
|
+
runnablesStyleEl.setAttribute('id', 'tagPillStyle');
|
|
353
|
+
runnablesStyleEl.innerHTML = defaultStyles;
|
|
354
|
+
runnables?.appendChild(runnablesStyleEl);
|
|
316
355
|
}
|
|
317
356
|
|
|
318
|
-
|
|
319
|
-
|
|
357
|
+
const testsAndSuites =
|
|
358
|
+
window.top?.document.querySelectorAll('.test.runnable');
|
|
359
|
+
[...testsAndSuites].forEach((t) => {
|
|
360
|
+
const header = t.querySelector('.collapsible-header');
|
|
361
|
+
const collapsibleHeaderText = header?.querySelector(
|
|
362
|
+
'.collapsible-header-text'
|
|
363
|
+
);
|
|
364
|
+
if (!collapsibleHeaderText.className.includes('flex flex-wrap gap-2')) {
|
|
365
|
+
collapsibleHeaderText.className += ' flex flex-wrap gap-2';
|
|
366
|
+
}
|
|
367
|
+
const title = header.querySelector('.runnable-title');
|
|
368
|
+
const testName = title.innerText.split('\n')[0];
|
|
369
|
+
const allSpecTags = Cypress.env('specTags');
|
|
370
|
+
const testTag = getTagsForTitle(testName, allSpecTags);
|
|
371
|
+
if (t.querySelectorAll('[data-attribute="test-tags"]').length === 0) {
|
|
372
|
+
renderTagPills(testTag, title);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
function getTagsForTitle(title, fullTagsObj) {
|
|
379
|
+
const test = fullTagsObj[title];
|
|
380
|
+
if (!test) {
|
|
381
|
+
return []; // Title not found
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return [...test.effectiveTestTags, ...test.requiredTestTags];
|
|
320
385
|
}
|
|
321
386
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
387
|
+
function renderTagPills(tags, container) {
|
|
388
|
+
tags.forEach((tag) => {
|
|
389
|
+
const pill = document.createElement('button');
|
|
390
|
+
pill.textContent = tag;
|
|
391
|
+
pill.setAttribute('type', 'button');
|
|
392
|
+
pill.setAttribute('aria-label', 'Filter by test tag from grep plugin');
|
|
393
|
+
pill.setAttribute('data-attribute', 'test-tags');
|
|
394
|
+
|
|
395
|
+
const brightColors = [
|
|
396
|
+
'#FF7373', // Red
|
|
397
|
+
'#FFB673', // Orange
|
|
398
|
+
'#FFE673', // Yellow
|
|
399
|
+
'#CFFF73', // Lime
|
|
400
|
+
'#73FF78', // Light Green
|
|
401
|
+
'#73FFC6', // Aqua
|
|
402
|
+
'#73E6FF', // Sky Blue
|
|
403
|
+
'#73A6FF', // Blue
|
|
404
|
+
'#7373FF', // Indigo
|
|
405
|
+
'#B473FF', // Purple
|
|
406
|
+
'#E673FF', // Magenta
|
|
407
|
+
'#FF73B6', // Rose
|
|
408
|
+
'#FF6E6E', // Slightly different Red
|
|
409
|
+
'#FFAB73', // Peach
|
|
410
|
+
'#FFF473', // Pale Yellow
|
|
411
|
+
'#DFFF73', // Pale Lime
|
|
412
|
+
'#73FFB6', // Mint
|
|
413
|
+
'#73DFFF', // Light Blue
|
|
414
|
+
'#A673FF', // Lavender
|
|
415
|
+
];
|
|
416
|
+
|
|
417
|
+
function tagNameToColor(str) {
|
|
418
|
+
let hash = 0;
|
|
419
|
+
for (let i = 0; i < str.length; i++)
|
|
420
|
+
hash = str.charCodeAt(i) + ((hash << 7) - hash);
|
|
421
|
+
return Math.abs(hash % 6);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function getTagColor(tag) {
|
|
425
|
+
const hash = tagNameToColor(tag);
|
|
426
|
+
return brightColors[hash % brightColors.length];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const bgColor = getTagColor(tag);
|
|
430
|
+
|
|
431
|
+
pill.setAttribute(
|
|
432
|
+
'style',
|
|
433
|
+
`
|
|
434
|
+
background: ${bgColor};
|
|
435
|
+
color: black;
|
|
436
|
+
padding: 0.1rem 0.2rem;
|
|
437
|
+
font-size: 0.875rem;
|
|
438
|
+
font-weight: bold;
|
|
439
|
+
border-radius: 2px;
|
|
440
|
+
display: inline-flex;
|
|
441
|
+
align-items: center;
|
|
442
|
+
white-space: nowrap;
|
|
443
|
+
cursor: pointer;
|
|
444
|
+
pointer-events: auto;
|
|
445
|
+
`
|
|
331
446
|
);
|
|
332
447
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
448
|
+
// Base styles
|
|
449
|
+
pill.className = `px-1 text-sm block inline-flex items-center whitespace-nowrap rounded`;
|
|
450
|
+
|
|
451
|
+
if (
|
|
452
|
+
// if the grep test toggle is checked, do not show checkboxes on each runnable
|
|
453
|
+
window.top?.document.querySelectorAll('#grepTestToggle:checked')
|
|
454
|
+
.length === 0
|
|
455
|
+
) {
|
|
456
|
+
// Handle selection toggle
|
|
457
|
+
pill.addEventListener('click', () => {
|
|
458
|
+
window.top?.document.querySelector('#grepTestToggle').click();
|
|
459
|
+
Cypress.grep(undefined, tag);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
container.after(pill);
|
|
464
|
+
});
|
|
336
465
|
}
|
|
337
466
|
|
|
338
467
|
Cypress.on('test:before:run', () => {
|
|
@@ -345,22 +474,24 @@ Cypress.on('test:before:run', () => {
|
|
|
345
474
|
}
|
|
346
475
|
});
|
|
347
476
|
|
|
348
|
-
// To account for when the collapsible runnables are removed, add back grep buttons
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
window.top?.document.querySelectorAll('#grepTestToggle:checked').length === 0
|
|
352
|
-
) {
|
|
353
|
-
// watching for changes to DOM structure
|
|
354
|
-
MutationObserver = window.MutationObserver;
|
|
477
|
+
// To account for when the collapsible runnables are removed, add back tags and grep buttons
|
|
478
|
+
// watching for changes to DOM structure
|
|
479
|
+
MutationObserver = window.MutationObserver;
|
|
355
480
|
|
|
356
|
-
|
|
481
|
+
var observer = new MutationObserver(function () {
|
|
482
|
+
if (
|
|
483
|
+
// if the grep test toggle is checked, do not show checkboxes on each runnable
|
|
484
|
+
window.top?.document.querySelectorAll('#grepTestToggle:checked').length ===
|
|
485
|
+
0
|
|
486
|
+
) {
|
|
357
487
|
// fired when a mutation occurs
|
|
358
488
|
addGrepButtons();
|
|
359
|
-
}
|
|
489
|
+
}
|
|
490
|
+
addTags();
|
|
491
|
+
});
|
|
360
492
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
493
|
+
// defining the window.top?.document to be observed by the observer
|
|
494
|
+
observer.observe(window.top?.document, {
|
|
495
|
+
subtree: true,
|
|
496
|
+
attributes: true,
|
|
497
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cypress-plugin-grep-boxes",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Cypress plugin that allows user to run specific tests in open mode.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"cypress-plugin"
|
|
10
10
|
],
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@bahmutov/cy-grep": "^2.0
|
|
13
|
-
"cypress": "^15.
|
|
12
|
+
"@bahmutov/cy-grep": "^2.1.0",
|
|
13
|
+
"cypress": "^15.5.0"
|
|
14
14
|
},
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"registry": "https://registry.npmjs.org/"
|