Inconsistent results with takeCoverageDelta for dynamic CSS coverage
See original GitHub issueI’m trying to see how dynamic code coverage for styles works using the devtools protocol. I’m manually evaluating a function which adds a class which was previously unused to the DOM which should ideally increase the coverage. But I keep getting inconsistent results in the coverage returned by takeCoverageDelta
. Sometimes it logs []
(wrong) and sometimes [{"styleSheetId":"35000.1","startOffset":0,"endOffset":31,"used":true}]
(correct)
I’m not sure if this is the right place to discuss this. Happy to move it to the Google groups if you can verify that my usage of CRI is not incorrect. Looks to me like some race condition that I’m unaware of or isnt documented in the chrome devtools docs.
Reproducible sample: I have a coverage.js
which launches chrome, connects to remote debugging port, and opens index.html
. This loads index.js
and style.css
.
// coverage.js
// Script to Launch and get CSS coverage
'use strict';
const CDP = require('chrome-remote-interface');
const ChromeLauncher = require('chrome-launcher');
const Path = require('path');
const styles = [];
const resources = [];
ChromeLauncher.launch({
port: 9222,
chromeFlags: ['--headless', '--disable-gpu'],
chromePath:
process.env.NODE_ENV === 'production' ? '/usr/bin/google-chrome' : undefined
})
.then(() => {
CDP().then(
async client => {
const { Page, Profiler, DOM, CSS, Runtime } = client;
// Enables all necessary domains
await Page.enable();
await Runtime.enable();
await DOM.enable();
await CSS.enable();
// Start capturing coverage data
await CSS.startRuleUsageTracking();
await Page.navigate({
url: `file://${Path.resolve(__dirname, './')}/index.html`
});
// Save the data for each style added to the document.
// This is because the rule usage data only includes styleSheetId.
// This helps map it back to the file name to which it belongs.
await CSS.styleSheetAdded(({ header }) => styles.push(header));
// Fires when all assets have finished loading
// This includes js, css, images, ads, etc.
await Page.loadEventFired();
const result = await Runtime.evaluate({
awaitPromise: true,
expression: 'coverMore()'
});
// Take a snapshot of all the coverage data ocne the load is complete
let { coverage: styleSheetCoverages } = await CSS.takeCoverageDelta();
// Sometimes logs []
// Sometimes logs [{"styleSheetId":"35000.1","startOffset":0,"endOffset":31,"used":true}]
console.log(JSON.stringify(styleSheetCoverages));
// Stop capturing coverage data
await CSS.stopRuleUsageTracking();
},
err => {
console.log('Error with remote interface', err);
}
);
})
.catch(err => {
console.log('Error with launcher', err);
});
<!-- index.html -->
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="app">
<div class="app-body"></div>
</div>
<script src="index.js"></script>
</body>
</html>
// index.js
const coverMore = () => {
const app = document.querySelector('.app');
app.classList.add('app-test4');
};
/* style.css */
.app-test4 {
display: flex;
}
Component | Version |
---|---|
Operating system | macOS Sierra 10.12.6 |
Node.js | 8.6.0 |
Chrome/Chromium/… | Chrome using Chrome Launcher 0.8.1 |
chrome-remote-interface | 0.25.1 |
Is Chrome running in a container? NO
Issue Analytics
- State:
- Created 6 years ago
- Comments:9 (5 by maintainers)
Top GitHub Comments
@karanjthakkar you’re welcome! The difference is explained here:
Conversely if you add a callback the return value is unimportant and the callback is executed every time an event occurs; it’s just a plain Node.js event emitter.
@cyrus-and Understood. I missed out on that line when you linked it previously. Again, thanks for explaining! Closing the issue 😃