Skip to content

Commit a3ea6b7

Browse files
authored
Merge pull request #43 from scratchfoundation/selenium-debug-info-files
test(gui): move Selenium debugging info to files in test-results/
2 parents 286b84c + 554c82e commit a3ea6b7

File tree

1 file changed

+49
-9
lines changed

1 file changed

+49
-9
lines changed

packages/scratch-gui/test/helpers/selenium-helper.js

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
// allow time for that so we get a more specific error message
33
jest.setTimeout(95000); // eslint-disable-line no-undef
44

5+
import {promises as fs} from 'fs';
6+
import path from 'path';
7+
58
import bindAll from 'lodash.bindall';
69
import webdriver from 'selenium-webdriver';
710

11+
import packageJson from '../../package.json';
12+
813
const {Button, By, until} = webdriver;
914

1015
const USE_HEADLESS = process.env.USE_HEADLESS !== 'no';
@@ -14,6 +19,31 @@ const USE_HEADLESS = process.env.USE_HEADLESS !== 'no';
1419
// The Jasmine default timeout is 30 seconds so make sure this is lower.
1520
const DEFAULT_TIMEOUT_MILLISECONDS = 20 * 1000;
1621

22+
// There doesn't seem to be a way to ask Jest (or jest-junit) for its output directory. The idea here is that if we
23+
// change the way we define the output directory in package.json, move it to a separate config file, etc.,
24+
// a helpful error is better than a confusing error or silently dropping error output from CI.
25+
const testResultsDir = packageJson.jest.reporters
26+
.map(r => r[1].outputDirectory)
27+
.filter(x => x)[0];
28+
if (!testResultsDir) {
29+
throw new Error('Could not determine Jest test results directory');
30+
}
31+
32+
/**
33+
* Recursively check if this error or any errors in its causal chain have been "enhanced" by `enhanceError`.
34+
* @param {Error} error The error to check.
35+
* @returns {boolean} True if the error or any of its causes have been enhanced.
36+
*/
37+
const isEnhancedError = error => {
38+
while (error) {
39+
if (error.scratchEnhancedError) {
40+
return true;
41+
}
42+
error = error.cause;
43+
}
44+
return false;
45+
};
46+
1747
/**
1848
* Add more debug information to an error:
1949
* - Merge a causal error into an outer error with valuable stack information
@@ -26,6 +56,7 @@ const DEFAULT_TIMEOUT_MILLISECONDS = 20 * 1000;
2656
* @returns {Promise<Error>} The outerError, with the cause embedded.
2757
*/
2858
const enhanceError = async (outerError, cause, driver) => {
59+
outerError.scratchEnhancedError = true;
2960
if (cause) {
3061
// This is the official way to nest errors in modern Node.js, but Jest ignores this field.
3162
// It's here in case a future version uses it, or in case the caller does.
@@ -36,18 +67,27 @@ const enhanceError = async (outerError, cause, driver) => {
3667
} else {
3768
outerError.message += '\nCause: unknown';
3869
}
39-
if (driver) {
40-
const url = await driver.getCurrentUrl();
41-
const title = await driver.getTitle();
42-
const pageSource = await driver.getPageSource();
70+
// Don't make a second copy of this debug info if an inner error has already done it,
71+
// especially since retrieving the browser log is a destructive operation.
72+
if (driver && !isEnhancedError(cause)) {
73+
await fs.mkdir(testResultsDir, {recursive: true});
74+
const errorInfoDir = await fs.mkdtemp(`${testResultsDir}/selenium-error-`);
75+
outerError.message += `\nDebug info stored in: ${errorInfoDir}`;
76+
77+
const pageInfoPath = path.join(errorInfoDir, 'info.json');
78+
await fs.writeFile(pageInfoPath, JSON.stringify({
79+
currentUrl: await driver.getCurrentUrl(),
80+
pageTitle: await driver.getTitle()
81+
}, null, 2));
82+
83+
const pageSourcePath = path.join(errorInfoDir, 'page.html');
84+
await fs.writeFile(pageSourcePath, await driver.getPageSource());
85+
86+
const browserLogPath = path.join(errorInfoDir, 'browser-log.txt');
4387
const browserLogEntries = await driver.manage()
4488
.logs()
4589
.get('browser');
46-
const browserLogText = browserLogEntries.map(entry => entry.message).join('\n');
47-
outerError.message += `\nBrowser URL: ${url}`;
48-
outerError.message += `\nBrowser title: ${title}`;
49-
outerError.message += `\nBrowser logs:\n*****\n${browserLogText}\n*****\n`;
50-
outerError.message += `\nBrowser page source:\n*****\n${pageSource}\n*****\n`;
90+
await fs.writeFile(browserLogPath, JSON.stringify(browserLogEntries, null, 2));
5191
}
5292
return outerError;
5393
};

0 commit comments

Comments
 (0)