cypress-plugin-last-failed 1.0.2 โ 1.2.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/.github/workflows/main.yml +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/runFailed.js +20 -3
- package/src/index.js +16 -182
- package/src/toggle.js +195 -0
package/README.md
CHANGED
package/package.json
CHANGED
package/runFailed.js
CHANGED
|
@@ -10,20 +10,37 @@ async function runLastFailed() {
|
|
|
10
10
|
Ensure you are in the directory of your cypress config
|
|
11
11
|
Try running tests again with cypress run`;
|
|
12
12
|
|
|
13
|
-
const failedTestFilePath = `${appDir}/test-results/last-run.
|
|
13
|
+
const failedTestFilePath = `${appDir}/test-results/last-run.json`;
|
|
14
14
|
|
|
15
15
|
if (fs.existsSync(failedTestFilePath)) {
|
|
16
16
|
// Retrieve the failedTests from the file
|
|
17
17
|
const failedTests = await fs.promises.readFile(failedTestFilePath, 'utf8');
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// Retrieve the parent suite and tests in the results from test-results/last-run
|
|
20
|
+
const parentAndTest = JSON.parse(failedTests).map(({ parent, test }) => ({
|
|
21
|
+
parent,
|
|
22
|
+
test,
|
|
23
|
+
}));
|
|
24
|
+
// Combine parent suite and test together
|
|
25
|
+
const resultSet = new Set(
|
|
26
|
+
Object.values(parentAndTest).flatMap(
|
|
27
|
+
(parent) => parent.parent + ',' + parent.test + ';'
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
// Format string for use in grep functionality
|
|
31
|
+
const stringedTests = Array.from(resultSet)
|
|
32
|
+
.toString()
|
|
33
|
+
.replaceAll(',', ' ')
|
|
34
|
+
.slice(0, -1);
|
|
35
|
+
|
|
36
|
+
if (stringedTests.length > 0) {
|
|
20
37
|
// Allow for additional cli arguments to be passed to the run command
|
|
21
38
|
const runOptions = await cypress.cli.parseRunArguments(
|
|
22
39
|
process.argv.slice(2)
|
|
23
40
|
);
|
|
24
41
|
|
|
25
42
|
// Set cypress environment variables needed for running last failed tests
|
|
26
|
-
process.env.CYPRESS_grep = `${
|
|
43
|
+
process.env.CYPRESS_grep = `${stringedTests}`;
|
|
27
44
|
process.env.CYPRESS_grepFilterSpecs = true;
|
|
28
45
|
process.env.CYPRESS_grepOmitFiltered = true;
|
|
29
46
|
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
|
|
3
|
+
const failedTestToggle = require('./toggle');
|
|
4
4
|
/**
|
|
5
5
|
* Collects failed tests from the most recent Cypress test run
|
|
6
6
|
*
|
|
@@ -21,18 +21,23 @@ const collectFailingTests = (on, config) => {
|
|
|
21
21
|
for (i in results.runs) {
|
|
22
22
|
const tests = results.runs[i].tests
|
|
23
23
|
.filter((test) => test.state === 'failed')
|
|
24
|
-
.map((test) => test.title
|
|
24
|
+
.map((test) => test.title);
|
|
25
|
+
|
|
26
|
+
const spec = results.runs[i].spec.relative;
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
for (i in tests) {
|
|
29
|
+
let report = {
|
|
30
|
+
spec: spec,
|
|
31
|
+
parent: [...tests[i].slice(0, -1)],
|
|
32
|
+
test: tests[i].pop(),
|
|
33
|
+
};
|
|
34
|
+
// Only store non empty test titles
|
|
35
|
+
if (tests != '') {
|
|
36
|
+
failedTests.push(report);
|
|
37
|
+
}
|
|
29
38
|
}
|
|
30
39
|
}
|
|
31
40
|
|
|
32
|
-
const stringedTests = failedTests.toString();
|
|
33
|
-
// Prepare a string that can be read from cy-grep
|
|
34
|
-
const greppedTestFormat = stringedTests.replaceAll(',', '; ');
|
|
35
|
-
|
|
36
41
|
// Use the cypress.config directory for path for storing test-results
|
|
37
42
|
const failedTestFileDirectory = `${path.dirname(
|
|
38
43
|
config.configFile
|
|
@@ -44,183 +49,12 @@ const collectFailingTests = (on, config) => {
|
|
|
44
49
|
});
|
|
45
50
|
const lastRunReportFile = path.join(
|
|
46
51
|
`${failedTestFileDirectory}`,
|
|
47
|
-
'last-run.
|
|
52
|
+
'last-run.json'
|
|
48
53
|
);
|
|
49
|
-
await fs.promises.writeFile(lastRunReportFile,
|
|
54
|
+
await fs.promises.writeFile(lastRunReportFile, JSON.stringify(failedTests));
|
|
50
55
|
});
|
|
51
56
|
|
|
52
57
|
return collectFailingTests;
|
|
53
58
|
};
|
|
54
59
|
|
|
55
|
-
/**
|
|
56
|
-
* Find and grep all the failed test titles designated within the Cypress Test Runner UI.
|
|
57
|
-
*
|
|
58
|
-
* Any retried tests that failed but ultimately passed will not be included.
|
|
59
|
-
*
|
|
60
|
-
* See README for recommendation on handling skipped tests ordinarily seen within the Cypress Test Runner UI.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
const grepFailed = () => {
|
|
64
|
-
// @ts-ignore
|
|
65
|
-
const failedTestTitles = [];
|
|
66
|
-
|
|
67
|
-
const failedTests = window.top?.document.querySelectorAll(
|
|
68
|
-
'.test.runnable.runnable-failed'
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
[...failedTests].forEach((test) => {
|
|
72
|
-
failedTestTitles.push(test.innerText.split('\n')[0]);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
if (!failedTestTitles.length) {
|
|
76
|
-
console.log('No failed tests found');
|
|
77
|
-
} else {
|
|
78
|
-
console.log('running only the failed tests');
|
|
79
|
-
const grepTitles = failedTestTitles.join('; ');
|
|
80
|
-
console.log(grepTitles);
|
|
81
|
-
// @ts-ignore
|
|
82
|
-
Cypress.grep(grepTitles);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Toggle for use within a spec file during `cypress open`
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
const failedTestToggle = () => {
|
|
91
|
-
const hasStyles = top?.document.querySelector('#runFailedStyle');
|
|
92
|
-
const hasToggleButton = top?.document.querySelector('#runFailedToggle');
|
|
93
|
-
const defaultStyles = `
|
|
94
|
-
.reporter header {
|
|
95
|
-
overflow: visible;
|
|
96
|
-
z-index: 2;
|
|
97
|
-
}
|
|
98
|
-
#runFailedControls {
|
|
99
|
-
position: relative;
|
|
100
|
-
display: inline-block;
|
|
101
|
-
}
|
|
102
|
-
#runFailedToggle {
|
|
103
|
-
display: none;
|
|
104
|
-
}
|
|
105
|
-
#runFailedControls label {
|
|
106
|
-
background-color: transparent;
|
|
107
|
-
padding-top: 5px;
|
|
108
|
-
}
|
|
109
|
-
#runFailedControls #runFailedTooltip {
|
|
110
|
-
visibility: hidden;
|
|
111
|
-
width: 134px;
|
|
112
|
-
background-color: #f3f4fa;
|
|
113
|
-
color: #1b1e2e;
|
|
114
|
-
text-align: center;
|
|
115
|
-
padding: 5px;
|
|
116
|
-
border-radius: 3px;
|
|
117
|
-
position: absolute;
|
|
118
|
-
z-index: 1;
|
|
119
|
-
top: 27px;
|
|
120
|
-
left: 0px;
|
|
121
|
-
height: 28px;
|
|
122
|
-
}
|
|
123
|
-
#runFailedControls:hover #runFailedTooltip {
|
|
124
|
-
visibility: visible;
|
|
125
|
-
}
|
|
126
|
-
#runFailedButton #runFailedLabel {
|
|
127
|
-
cursor: pointer;
|
|
128
|
-
}
|
|
129
|
-
#runFailedTooltip::after {
|
|
130
|
-
content: " ";
|
|
131
|
-
position: absolute;
|
|
132
|
-
bottom: 100%; /* At the top of the tooltip */
|
|
133
|
-
right: 85%;
|
|
134
|
-
margin-left: -5px;
|
|
135
|
-
border-width: 5px;
|
|
136
|
-
border-style: solid;
|
|
137
|
-
border-color: transparent transparent #f3f4fa transparent;
|
|
138
|
-
}
|
|
139
|
-
.reporter:has(#runFailed:checked) .command.command-name-request:has(.command-is-event) {
|
|
140
|
-
display:none
|
|
141
|
-
}
|
|
142
|
-
`;
|
|
143
|
-
const turnOffRunFailedIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#f59aa9" class="bi bi-filter-circle" viewBox="0 0 16 16">
|
|
144
|
-
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
|
|
145
|
-
<path d="M7 11.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5"/>
|
|
146
|
-
</svg>`;
|
|
147
|
-
|
|
148
|
-
const turnOnRunFailedIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#f59aa9" class="bi bi-filter-circle-fill" viewBox="0 0 16 16">
|
|
149
|
-
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16M3.5 5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1 0-1M5 8.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m2 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5"/>
|
|
150
|
-
</svg>`;
|
|
151
|
-
|
|
152
|
-
const turnOffRunFailedDescription = 'Filter failed tests';
|
|
153
|
-
const turnOnRunFailedDescription = 'Unfilter failed tests';
|
|
154
|
-
|
|
155
|
-
// append styles
|
|
156
|
-
if (!hasStyles) {
|
|
157
|
-
const reporterEl = top?.document.querySelector('#unified-reporter');
|
|
158
|
-
const reporterStyleEl = document.createElement('style');
|
|
159
|
-
reporterStyleEl.setAttribute('id', 'runFailedStyle');
|
|
160
|
-
reporterStyleEl.innerHTML = defaultStyles;
|
|
161
|
-
reporterEl?.appendChild(reporterStyleEl);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (!hasToggleButton) {
|
|
165
|
-
const header = top?.document.querySelector('#unified-reporter header');
|
|
166
|
-
const headerToggleDiv = document.createElement('div');
|
|
167
|
-
const headerToggleSpan = document.createElement('span');
|
|
168
|
-
const headerToggleTooltip = document.createElement('span');
|
|
169
|
-
const headerToggleButton = document.createElement('button');
|
|
170
|
-
const headerToggleInput = document.createElement('input');
|
|
171
|
-
const headerToggleLabel = document.createElement('label');
|
|
172
|
-
|
|
173
|
-
headerToggleInput.setAttribute('type', 'checkbox');
|
|
174
|
-
|
|
175
|
-
headerToggleInput.setAttribute('id', 'runFailedToggle');
|
|
176
|
-
headerToggleLabel.setAttribute('for', 'runFailedToggle');
|
|
177
|
-
headerToggleLabel.setAttribute('id', 'runFailedLabel');
|
|
178
|
-
headerToggleLabel.innerHTML = turnOffRunFailedIcon;
|
|
179
|
-
|
|
180
|
-
headerToggleDiv.setAttribute('class', 'controls');
|
|
181
|
-
headerToggleDiv.setAttribute('id', 'runFailedControls');
|
|
182
|
-
headerToggleTooltip.setAttribute('id', 'runFailedTooltip');
|
|
183
|
-
headerToggleTooltip.innerText = turnOffRunFailedDescription;
|
|
184
|
-
headerToggleButton.setAttribute('aria-label', turnOffRunFailedDescription);
|
|
185
|
-
headerToggleButton.setAttribute('id', 'runFailedButton');
|
|
186
|
-
|
|
187
|
-
header?.appendChild(headerToggleDiv);
|
|
188
|
-
headerToggleDiv?.appendChild(headerToggleSpan);
|
|
189
|
-
headerToggleDiv?.appendChild(headerToggleTooltip);
|
|
190
|
-
headerToggleSpan?.appendChild(headerToggleButton);
|
|
191
|
-
headerToggleButton?.appendChild(headerToggleInput);
|
|
192
|
-
headerToggleButton?.appendChild(headerToggleLabel);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const runFailedElement = top.document.querySelector('#runFailedToggle');
|
|
196
|
-
const runFailedLabelElement = top.document.querySelector(
|
|
197
|
-
'[for=runFailedToggle]'
|
|
198
|
-
);
|
|
199
|
-
const runFailedTooltipElement =
|
|
200
|
-
top.document.querySelector('#runFailedTooltip');
|
|
201
|
-
|
|
202
|
-
runFailedElement?.addEventListener('change', (e) => {
|
|
203
|
-
const stopBtn = window.top.document.querySelector('.reporter .stop');
|
|
204
|
-
|
|
205
|
-
if (e.target.checked) {
|
|
206
|
-
if (stopBtn) {
|
|
207
|
-
stopBtn.click();
|
|
208
|
-
}
|
|
209
|
-
// when checked, grep only failed tests in spec
|
|
210
|
-
grepFailed();
|
|
211
|
-
|
|
212
|
-
runFailedLabelElement.innerHTML = turnOnRunFailedIcon;
|
|
213
|
-
runFailedTooltipElement.innerHTML = turnOnRunFailedDescription;
|
|
214
|
-
} else {
|
|
215
|
-
if (stopBtn) {
|
|
216
|
-
stopBtn.click();
|
|
217
|
-
}
|
|
218
|
-
// when unchecked, ungrep and show all tests in spec
|
|
219
|
-
Cypress.grep();
|
|
220
|
-
runFailedLabelElement.innerHTML = turnOffRunFailedIcon;
|
|
221
|
-
runFailedTooltipElement.innerHTML = turnOffRunFailedDescription;
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
};
|
|
225
|
-
|
|
226
60
|
module.exports = { collectFailingTests, failedTestToggle };
|
package/src/toggle.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find and grep all the failed test titles designated within the Cypress Test Runner UI.
|
|
3
|
+
*
|
|
4
|
+
* Any retried tests that failed but ultimately passed will not be included.
|
|
5
|
+
*
|
|
6
|
+
* See README for recommendation on handling skipped tests ordinarily seen within the Cypress Test Runner UI.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const grepFailed = () => {
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
const failedTestTitles = [];
|
|
12
|
+
|
|
13
|
+
const failedTests = window.top?.document.querySelectorAll(
|
|
14
|
+
'.test.runnable.runnable-failed'
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
[...failedTests].forEach((test) => {
|
|
18
|
+
failedTestTitles.push(test.innerText.split('\n')[0]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (!failedTestTitles.length) {
|
|
22
|
+
console.log('No failed tests found');
|
|
23
|
+
} else {
|
|
24
|
+
console.log('running only the failed tests');
|
|
25
|
+
const grepTitles = failedTestTitles.join('; ');
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
Cypress.grep(grepTitles);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Toggle for use within a spec file during `cypress open`
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
const failedTestToggle = () => {
|
|
36
|
+
const hasStyles = top?.document.querySelector('#runFailedStyle');
|
|
37
|
+
const hasToggleButton = top?.document.querySelector('#runFailedToggle');
|
|
38
|
+
const defaultStyles = `
|
|
39
|
+
.reporter header {
|
|
40
|
+
overflow: visible;
|
|
41
|
+
z-index: 2;
|
|
42
|
+
}
|
|
43
|
+
#runFailedControls {
|
|
44
|
+
position: relative;
|
|
45
|
+
display: inline-block;
|
|
46
|
+
}
|
|
47
|
+
#runFailedToggle {
|
|
48
|
+
display: none;
|
|
49
|
+
}
|
|
50
|
+
#runFailedControls label {
|
|
51
|
+
background-color: transparent;
|
|
52
|
+
padding-top: 5px;
|
|
53
|
+
}
|
|
54
|
+
#runFailedControls #runFailedTooltip {
|
|
55
|
+
visibility: hidden;
|
|
56
|
+
width: 134px;
|
|
57
|
+
background-color: #f3f4fa;
|
|
58
|
+
color: #1b1e2e;
|
|
59
|
+
text-align: center;
|
|
60
|
+
padding: 5px;
|
|
61
|
+
border-radius: 3px;
|
|
62
|
+
position: absolute;
|
|
63
|
+
z-index: 1;
|
|
64
|
+
top: 27px;
|
|
65
|
+
left: 0px;
|
|
66
|
+
height: 28px;
|
|
67
|
+
}
|
|
68
|
+
#runFailedControls:hover #runFailedTooltip {
|
|
69
|
+
visibility: visible;
|
|
70
|
+
}
|
|
71
|
+
#runFailedButton #runFailedLabel {
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
}
|
|
74
|
+
#runFailedTooltip::after {
|
|
75
|
+
content: " ";
|
|
76
|
+
position: absolute;
|
|
77
|
+
bottom: 100%; /* At the top of the tooltip */
|
|
78
|
+
right: 85%;
|
|
79
|
+
margin-left: -5px;
|
|
80
|
+
border-width: 5px;
|
|
81
|
+
border-style: solid;
|
|
82
|
+
border-color: transparent transparent #f3f4fa transparent;
|
|
83
|
+
}
|
|
84
|
+
.reporter:has(#runFailed:checked) .command.command-name-request:has(.command-is-event) {
|
|
85
|
+
display:none
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
const turnOffRunFailedIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#f59aa9" class="bi bi-filter-circle" viewBox="0 0 16 16">
|
|
89
|
+
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
|
|
90
|
+
<path d="M7 11.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5"/>
|
|
91
|
+
</svg>`;
|
|
92
|
+
|
|
93
|
+
const turnOnRunFailedIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#f59aa9" class="bi bi-filter-circle-fill" viewBox="0 0 16 16">
|
|
94
|
+
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16M3.5 5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1 0-1M5 8.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m2 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5"/>
|
|
95
|
+
</svg>`;
|
|
96
|
+
|
|
97
|
+
const turnOffRunFailedDescription = 'Filter failed tests';
|
|
98
|
+
const turnOnRunFailedDescription = 'Unfilter failed tests';
|
|
99
|
+
|
|
100
|
+
// append styles
|
|
101
|
+
if (!hasStyles) {
|
|
102
|
+
const reporterEl = top?.document.querySelector('#unified-reporter');
|
|
103
|
+
const reporterStyleEl = document.createElement('style');
|
|
104
|
+
reporterStyleEl.setAttribute('id', 'runFailedStyle');
|
|
105
|
+
reporterStyleEl.innerHTML = defaultStyles;
|
|
106
|
+
reporterEl?.appendChild(reporterStyleEl);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!hasToggleButton) {
|
|
110
|
+
const header = top?.document.querySelector('#unified-reporter header');
|
|
111
|
+
const headerToggleDiv = document.createElement('div');
|
|
112
|
+
const headerToggleSpan = document.createElement('span');
|
|
113
|
+
const headerToggleTooltip = document.createElement('span');
|
|
114
|
+
const headerToggleButton = document.createElement('button');
|
|
115
|
+
const headerToggleInput = document.createElement('input');
|
|
116
|
+
const headerToggleLabel = document.createElement('label');
|
|
117
|
+
|
|
118
|
+
headerToggleInput.setAttribute('type', 'checkbox');
|
|
119
|
+
|
|
120
|
+
headerToggleInput.setAttribute('id', 'runFailedToggle');
|
|
121
|
+
headerToggleLabel.setAttribute('for', 'runFailedToggle');
|
|
122
|
+
headerToggleLabel.setAttribute('id', 'runFailedLabel');
|
|
123
|
+
headerToggleLabel.innerHTML = turnOffRunFailedIcon;
|
|
124
|
+
|
|
125
|
+
headerToggleDiv.setAttribute('class', 'controls');
|
|
126
|
+
headerToggleDiv.setAttribute('id', 'runFailedControls');
|
|
127
|
+
headerToggleTooltip.setAttribute('id', 'runFailedTooltip');
|
|
128
|
+
headerToggleTooltip.innerText = turnOffRunFailedDescription;
|
|
129
|
+
headerToggleButton.setAttribute('aria-label', turnOffRunFailedDescription);
|
|
130
|
+
headerToggleButton.setAttribute('id', 'runFailedButton');
|
|
131
|
+
|
|
132
|
+
header?.appendChild(headerToggleDiv);
|
|
133
|
+
headerToggleDiv?.appendChild(headerToggleSpan);
|
|
134
|
+
headerToggleDiv?.appendChild(headerToggleTooltip);
|
|
135
|
+
headerToggleSpan?.appendChild(headerToggleButton);
|
|
136
|
+
headerToggleButton?.appendChild(headerToggleInput);
|
|
137
|
+
headerToggleButton?.appendChild(headerToggleLabel);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const runFailedElement = top.document.querySelector('#runFailedToggle');
|
|
141
|
+
const runFailedLabelElement = top.document.querySelector(
|
|
142
|
+
'[for=runFailedToggle]'
|
|
143
|
+
);
|
|
144
|
+
const runFailedTooltipElement =
|
|
145
|
+
top.document.querySelector('#runFailedTooltip');
|
|
146
|
+
|
|
147
|
+
runFailedElement?.addEventListener('change', (e) => {
|
|
148
|
+
const stopBtn = window.top.document.querySelector('.reporter .stop');
|
|
149
|
+
|
|
150
|
+
if (e.target.checked) {
|
|
151
|
+
if (stopBtn) {
|
|
152
|
+
stopBtn.click();
|
|
153
|
+
}
|
|
154
|
+
// when checked, grep only failed tests in spec
|
|
155
|
+
grepFailed();
|
|
156
|
+
|
|
157
|
+
runFailedLabelElement.innerHTML = turnOnRunFailedIcon;
|
|
158
|
+
runFailedTooltipElement.innerHTML = turnOnRunFailedDescription;
|
|
159
|
+
} else {
|
|
160
|
+
if (stopBtn) {
|
|
161
|
+
stopBtn.click();
|
|
162
|
+
}
|
|
163
|
+
// when unchecked, ungrep and show all tests in spec
|
|
164
|
+
Cypress.grep();
|
|
165
|
+
runFailedLabelElement.innerHTML = turnOffRunFailedIcon;
|
|
166
|
+
runFailedTooltipElement.innerHTML = turnOffRunFailedDescription;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
// Wrapping logic within isInteractive check
|
|
170
|
+
// This targets cypress open mode where user can switch specs
|
|
171
|
+
if (Cypress.config('isInteractive')) {
|
|
172
|
+
Cypress.on('window:unload', () => {
|
|
173
|
+
// Store the current Cypress test runner url
|
|
174
|
+
// This is to check against any spec change in test runner while the grep filter is activated
|
|
175
|
+
// If a user does switch spec while filter is active, the filter will be reset
|
|
176
|
+
const sidebarRunsLinkPage = window.top?.document.querySelector(
|
|
177
|
+
'[data-cy="sidebar-link-runs-page"]'
|
|
178
|
+
);
|
|
179
|
+
const runFailedToggleElement =
|
|
180
|
+
window.top?.document.querySelector('#runFailedToggle');
|
|
181
|
+
|
|
182
|
+
if (
|
|
183
|
+
window.top?.document.URL !=
|
|
184
|
+
sidebarRunsLinkPage.getAttribute('data-url') &&
|
|
185
|
+
runFailedToggleElement.checked
|
|
186
|
+
) {
|
|
187
|
+
runFailedToggleElement.click();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
sidebarRunsLinkPage.setAttribute('data-url', window.top?.document.URL);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
module.exports = failedTestToggle;
|