Skip to content
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

Add DomNode renderer #2206

Merged
merged 9 commits into from
May 15, 2017
Merged

Add DomNode renderer #2206

merged 9 commits into from
May 15, 2017

Conversation

paulirish
Copy link
Member

@paulirish paulirish commented May 10, 2017

Adding a new node/element renderer for the report. Primarily assisting all the a11y audits right now.

I've also added a --a11y CLI flag because 1) it was super easy and 2) it was really handy. But I can revert, no big deal.

This also enables node revealing/hovering in devtools. The WIP DevTools-side patch:
https://codereview.chromium.org/2849463002/diff/1/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js

It looks like this in the standalone report:
image

const path = [];
while (node && node.parentNode) {
const index = getNodeIndex(node);
path.push([index, node.nodeName]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this pavel's special node selector methodology? what would be the downside to augmenting a regular CSS selector with nth-child?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah in the protocol docs it says "proprietary format". :)

impl's: backend side,frontend side

downsides of using selectors:

  1. can't reference text nodes, document fragments, or the doctype node
  2. can't pierce shadow dom

* @param {!DetailsRenderer.NodeDetailsJSON} item
* @return {!Element}
*/
_renderNode(item) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node is slightly ambiguous at this level, can we make it DOMNode or something? when I just looked at the title of the PR I thought it was a renderer running in "node.js" 😆

* @param {string} text
* @return {!Node}
*/
createText(text) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't seem used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true.

@@ -66,6 +67,8 @@ if (cliFlags.configPath) {
config = require(cliFlags.configPath);
} else if (cliFlags.perf) {
config = perfOnlyConfig;
} else if (cliFlags.a11y) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only downside here is that people might think you could do lighthouse --perf --a11y and get both, what if we supported that by nixing the config files and just appending each category that's enabled to onlyCategories of a default extending config

I can pickup that separately though

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh true. ill probably kick this out of the PR. :)

@@ -82,6 +82,7 @@ export function getFlags() {
'chrome-flags':
'Custom flags to pass to Chrome (space-delimited). For a full list of flags, see http://peter.sh/experiments/chromium-command-line-switches/.',
'perf': 'Use a performance-test-only configuration',
'a11y': 'Use an accessibility-test-only configuration',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you keep the flag, please update the readme.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ill probably nuke, but thx!

});

// Adapated from DevTools' SDK.DOMNode.prototype.path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adapted


// Adapated from DevTools' SDK.DOMNode.prototype.path
// https://github.com/ChromeDevTools/devtools-frontend/blob/7a2e162ddefd/front_end/sdk/DOMModel.js#L530-L552
// TODO: Doesn't handle frames or shadow roots...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you file a bug on this? We have some other "handle shadow root" updates to make in the codebase. We can address them all after io.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's also work ongoing in axe to support shadow dom. @alice may know more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any updates here, sorry. I know Marcy was thinking of taking a look at it but she might have gotten swamped with other things.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filed #2243

// https://github.com/ChromeDevTools/devtools-frontend/blob/7a2e162ddefd/front_end/sdk/DOMModel.js#L530-L552
// TODO: Doesn't handle frames or shadow roots...
function getNodePath(node) {
/* global Node */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer this at the top.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will move to the top top.

look like global and env are file-wide so we couldnt have it be scoped to a function anyway. bummer.

while (node = node.previousSibling) {
// skip empty text nodes
if (node.nodeType === Node.TEXT_NODE &&
node.textContent.trim().length === 0) continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 space indent

return path.join(',');
}

function getOuterHTMLSnippet(node) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs

@paulirish paulirish changed the title Add Node renderer Add DomNode renderer May 10, 2017
@paulirish
Copy link
Member Author

I'm getting a ": Object reference chain is too long" error on some pages:
image

It's due to an object being > 1000 objects deep.

I imagine it's something that happens to the Axe result object on big pages (e.g. https://developers.google.com/web/tools/chrome-devtools/ ) but it's not clear.

cc @robdodson

@robdodson
Copy link
Contributor

Hm I'm not able to reproduce this error. Do you have some specific steps I could follow? I tried running axe extension, axe cli, and audits against the link you provided and they all work fine for me.

@paulirish
Copy link
Member Author

Hm I'm not able to reproduce this error. Do you have some specific steps I could follow?

I'd say try it with this patch? it's possible the new elemRef option is what's triggering it.

@dylanb
Copy link

dylanb commented May 11, 2017

@paulirish I was also not able to reproduce this. I tried using an extension and I tried by simply going to the page, using the console to execute the axe-core 2.2.0 Javascript and then running axe.run - is there some particular environment I need to reproduce this?

@paulirish
Copy link
Member Author

I'm getting a ": Object reference chain is too long" error on some pages:

I'm pretty sure I managed to squash all these.
I pretty much neuter the return object from axe, in order to verify there are no circular references within it. 4b00b65

thank you guys for testing this and trying to give it a shot.

@paulirish
Copy link
Member Author

@dylanb i don't think it'll be a problem for us anymore, but ultimately the challenge was that we wanted JSON.stringify(axeResultObject) to succeed and it was running into circular JSON problems. It doesn't necessarily have to be a requirement that the axeResultObject is serializable, but it might help other consumers of the data.
Cheers!

@paulirish
Copy link
Member Author

@patrickhulce this is ready for another look right?

@patrickhulce
Copy link
Collaborator

yep tests passing and ready for review

@dylanb
Copy link

dylanb commented May 19, 2017

@paulirish It was in fact a bug, it has been fixed. Upgrade to 2.2.1 to get the fix dequelabs/axe-core#334

robdodson added a commit that referenced this pull request May 22, 2017
paulirish pushed a commit that referenced this pull request May 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants