-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[no ticket][risk=no] Puppeteer test log improvement #4660
Conversation
await savePageToFile(this.page); | ||
await takeScreenshot(this.page); | ||
throw (err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant. saving screenshot and html is done in
handleTestEvent
@@ -3,7 +3,6 @@ const { TEST_MODE } = process.env; | |||
|
|||
module.exports = { | |||
"verbose": false, | |||
"bail": 1, // Stop running tests after `n` failures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setting bail
prevents test log write to file. Alternative is implemented in PuppeteerCustomEnvironment
's handleTestEvent
.
e2e/puppeteer-custom-environment.ts
Outdated
if (this.failedTest && event.name === 'test_start') { | ||
event.test.mode = 'skip'; | ||
} | ||
if (super.handleTestEvent) { | ||
super.handleTestEvent(event, state) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternative to Jest bail
.
#6527 comment
@@ -74,6 +69,7 @@ | |||
"tslint-config-prettier": "1.18.0", | |||
"tslint-eslint-rules": "5.4.0", | |||
"tslint-microsoft-contrib": "6.2.0", | |||
"typescript": "4.1.2" | |||
"typescript": "4.1.2", | |||
"winston": "^3.3.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
winston
: timestamp and saving to file.
@@ -7,8 +7,8 @@ | |||
"license": "BSD", | |||
"scripts": { | |||
"impersonate-test-user": "env-cmd -x ../api/project.rb generate-impersonated-user-token --impersonated-user=\\$USER_NAME --output-token-filename=../e2e/puppeteer-access-token.txt", | |||
"_test": "yarn impersonate-test-user && jest", | |||
"_test:debugTest": "yarn impersonate-test-user && node --inspect-brk node_modules/.bin/jest", | |||
"_test": "yarn impersonate-test-user && jest --no-color", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ansi code makes test log harder to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, thanks - a couple of questions on this
@@ -82,6 +85,7 @@ beforeEach(async () => { | |||
'/cdrVersions', | |||
'/config', | |||
'/user-recent-workspaces', | |||
'/user-recent-resources', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First time seeing this list. This should have a comment about why you would add something to this list.
Also, page-visits does not have a /, this seems like a bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
console.info(`Running ${path.parse(test.path).name} at ${time}`); | ||
} | ||
|
||
// @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? Aren't you in a JS file anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tslint is checking all files (.ts, .js) because tsconfig.json
is config with "inclue": ["/*"]
. tslint is soon to be replaced by eslint. We can safely ignore this "bug" at this time.
e2e/libs/jest-reporter.js
Outdated
}); | ||
|
||
// Save test results to a file. | ||
if (!fs.existsSync(this.logDir)) fs.mkdirSync(this.logDir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: generally we avoid 1 line if statements like this in the codebase, or without brackets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected.
|
||
constructor(globalConfig, options) { | ||
if (globalConfig.verbose === true) { | ||
throw Error("Verbose must be false or Console messages won't be available.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this just be an console error? Is there no situation where you'd want to run like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In "verbose": true
mode, console logs are not saved by jest internally, so logs won't be available to onTestResult
function. I want to stop the test if it was changed. IMO, there isn't any good reason to use verbose: true
.
e2e/libs/jest-reporter.js
Outdated
// Get test name. | ||
const today = new Date(); | ||
const testName = path.parse(testResult.testFilePath).name; | ||
const testLog = `${this.logDir}/${testName}-${today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate()}.log`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the date included here? This seems like an odd granularity to choose. If you're trying to use this to get a unique filename, you'll probably need to be more specific (e.g. minute-level). If you want to overwrite previous files, then you may as well just exclude the date entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I want overwrite. Removed time string.
e2e/puppeteer-custom-environment.ts
Outdated
break; | ||
default: | ||
break; | ||
} | ||
|
||
if (this.failedTest && event.name === 'test_start') { | ||
event.test.mode = 'skip'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what is happening here, please add comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jest-circus is used as jest runner. It hooks into test event and state data.
It's fail fast. Because I can't use bail
option with a custom logger, I have to find another way to stop other tests from running after first failure. If first failure has happened, all following unexecuted tests will be marked as skip.
Comments also added to file.
format: format.combine( | ||
format.prettyPrint(), | ||
format.splat(), | ||
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
e2e/libs/jest-reporter.js
Outdated
options: { flags: 'w' }, | ||
handleExceptions: true, | ||
}); | ||
fileLogger.clear().add(transports); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain the decision to use a single logger and then replace the output file - instead of creating a separate logger for each test case? Could you not just create a new one right here rather than mutating shared global state?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I'm creating a new instance of winston logger here. Creating a separate log file for each test case. I didn't want to include fileLogger
here is because it might be reusable for other purpose in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought: I think I know what you meant. It's a good idea.
Moving fileLogger
code to here. creating a new log file for every test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I realized I asked for this, but am I understanding correctly that now the network log / console logs will not be in the individual test case log files? If so - would probably just revert to the previous approach if you can't use individual loggers there.
It will be very useful to have a clear separation of network logs across test cases - right now it's hard to tell since you have to scan the logs to know how far back you can look for the problematic test case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test network and console logs will be saved in individual test log file. they're not lost. It should be easier to read the test log when a failure has happened.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, I do seem them in the Circle run. I'm confused as to how they are getting there though, since this initial jest setup seems to reference the global logger: https://github.com/all-of-us/workbench/pull/4660/files#diff-9771f32e200b100d3bf9acedfc38dae6209ad815c5e214a31719188ddd392f1dR128
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. That logger
object is a separate winston logger that only logs to console. It doesn't have a file transport.
However, console logs are automatically saved by jest and later they can be retrieved in onTestResult
function when verbose: false
.
e2e/jest.test-setup.ts
Outdated
return jsHandle.executionContext().evaluate(obj => { | ||
if (obj instanceof Error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use brackets, also please add a comment - I don't follow this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
d2d8d0b
to
12f9dc0
Compare
} catch (err) { | ||
console.error(`❗ ${title}\nException occurred when getting error.\n${err}`); | ||
console.error(`❗ "${title}"\nException occurred when getting page error.\n${err}`); | ||
} | ||
}); | ||
|
||
page.on('pageerror', async (error) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: Somehow logging of console pageerror
and error
are not working. I don't have a solution at this time.
console.error
PAGEERROR: "Edit Workspace | [Test] All of Us Researcher Workbench"
Error: Object
Object
219 | const title = await getPageTitle();
220 | try {
> 221 | console.error(`PAGEERROR: "${title}"\n${error.toString()}\n${error.message}\n${error.stack}`);
| ^
222 | console.log('');
223 | } catch (err) {
224 | console.error(`❗ "${title}"\nPage exception occurred when getting pageerror.\n${err}`);
at jest.test-setup.ts:221:15
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One follow-up comment inline: please address before merging.
Also, from looking at the CircleCI page, I'm noticing it's actually pretty hard to know which logfile I should open to get more details, since I have to dig into the logs to figure out the test suite name, and map that to which one failed. Have you considered ways of addressing this? For example - if a test suite fails, maybe move these into separate pass/fail directories, or rename them to "FAILED", or possibly just remove the logfiles for passing suites?
Also - thoughts on splitting by individual test case, rather than test suite? I think test suite is probably OK for now, but something we may want to consider if this becomes problematic for debugging
e2e/libs/jest-reporter.js
Outdated
options: { flags: 'w' }, | ||
handleExceptions: true, | ||
}); | ||
fileLogger.clear().add(transports); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I realized I asked for this, but am I understanding correctly that now the network log / console logs will not be in the individual test case log files? If so - would probably just revert to the previous approach if you can't use individual loggers there.
It will be very useful to have a clear separation of network logs across test cases - right now it's hard to tell since you have to scan the logs to know how far back you can look for the problematic test case.
e2e/libs/jest-reporter.js
Outdated
let testLogName; | ||
testResult.testResults.forEach((result) => { | ||
const status = result.status; | ||
if (status === 'failed') { | ||
testLogName = `${this.logDir}/${testName}-FAILED.log`; | ||
} else { | ||
testLogName = `${this.logDir}/${testName}.log`; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More verbose code but it does the job to find failed test log a little easier. FAILED
string is added to log file name.
7a255a3
to
d5ae159
Compare
Adding log timestamp and saving single test log file.
New test logs structure: