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

core: fallback to selector, not tagName for nodeLabel #12727

Merged
merged 12 commits into from
Jul 6, 2021
Merged

core: fallback to selector, not tagName for nodeLabel #12727

merged 12 commits into from
Jul 6, 2021

Conversation

tannerdolby
Copy link
Contributor

Summary

Bug fix.

Under SEO, Lighthouse suggests that "Image elements do not have [alt] attributes"
But, it doesn't point out which image element doesn't have the alt attribute. (original comment)

After running:

  1. yarn and yarn build-all
  2. node --inspect-brk lighthouse-cli https://ravikirans.com/az-204-azure-exam-study-guide/

and then clicking on the correct target after navigating to about:inspect in chrome, the audit report correctly utilizes the fallback selector and doesn't throw any failed audit warnings for "Images not having [alt] attribute". Can include generated audit report if needed.

status Auditing: Image elements have `[alt]` attributes +22ms

Related Issues/PRs

Fixes #12668
Related #10421

@tannerdolby tannerdolby requested a review from a team as a code owner June 30, 2021 18:58
@tannerdolby tannerdolby requested review from patrickhulce and removed request for a team June 30, 2021 18:58
@google-cla
Copy link

google-cla bot commented Jun 30, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@tannerdolby
Copy link
Contributor Author

@googlebot I signed it!

@google-cla google-cla bot added cla: yes and removed cla: no labels Jun 30, 2021
@tannerdolby tannerdolby changed the title Fallback to selector instead of tagName in nodeLabel generation core: fallback to selector instead of tagName in nodeLabel generation Jun 30, 2021
@tannerdolby
Copy link
Contributor Author

Oh I see why the "pr title lint" failed, there is an expected PR title format ${type}(${optional-scope}): ${subject}, just updated that.

@@ -400,6 +400,7 @@ function getNodeLabel(element) {
}

const tagName = element.tagName.toLowerCase();
const selector = getNodeSelector(element);
Copy link
Collaborator

Choose a reason for hiding this comment

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

two options here to avoid calling getNodeSelector twice per call to getNodeDetails:

  1. have this function return null if no useful label, and use result of getNodeSelector as fallback in getNodeDetails (getNodeLabel(...) || selector)
  2. have getNodeSelector accept a default parameter and return that as default

Copy link
Contributor Author

@tannerdolby tannerdolby Jun 30, 2021

Choose a reason for hiding this comment

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

Yeah that makes sense, thanks for the review! I like option 1 to return null if no useful label, will implement the changes you requested shortly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

also you'll likely need to fix the tests (run yarn jest page-functions)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added the requested changes discussed in option 1, and yep two tests failed after running yarn jest page-functions

✕ Uses tag name for html tags (7 ms)
assert.strictEqual(received, expected)

    Expected value to strictly be equal to:
      "html"
    Received:
      null
✕ Uses tag name if there is no better label (2 ms)
...

@@ -177,16 +177,16 @@ describe('Page Functions', () => {
assert.equal(pageFunctions.getNodeLabel(el), Array(78).fill('a').join('') + '💡…');
});

it('Uses tag name for html tags', () => {
it('Returns null if nodeLabel is not usable for html tags', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a test case to getNodeDetails that covers the fallack?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! That's where my mind skipped, thank you, will commit change shortly :)

Copy link
Contributor Author

@tannerdolby tannerdolby Jun 30, 2021

Choose a reason for hiding this comment

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

@connorjclark quick question, when I try to use:

const el = dom.createElement("html");
assert.equal(pageFunctions.getNodeDetails(el), { ... nodeLabel: 'html' });

its saying I should be using jsdom as window is not defined but that is already handled at the beginning of the file. Am I missing some small detail to write this test for getNodeDetails()?

Copy link
Collaborator

@connorjclark connorjclark Jun 30, 2021

Choose a reason for hiding this comment

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

you can add a global.window = {} / global.window = undefined to make that work–the first few lines of getNodeDetails (which i'm just realizing we have no unit tests for... only smoke tests) expected there to be a window variable in the global scope.

Copy link
Contributor Author

@tannerdolby tannerdolby Jul 1, 2021

Choose a reason for hiding this comment

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

yeah that did the trick, I think I expected there to be a window variable in the global scope already too and was just stumped because there weren't any other unit tests that tested getNodeDetails and needed window.

(...which i'm just realizing we have no unit tests for... only smoke tests)

I'm happy to help write a few more unit tests for the other fields in details like devtoolsNodePath, selector, boundingRect etc similar to how were testing nodeLabel.

Copy link
Contributor Author

@tannerdolby tannerdolby Jul 1, 2021

Choose a reason for hiding this comment

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

Here is a simple test to make sure the selector value is being used as the fallback for nodeLabel in details. We could pluck each property from details using destructuring assignment to write a few unit tests for the other properties besides nodeLabel, unless each test needed the entire details object.

Haven't looked into testing the other properties in details but I thought this was a start for potentially writing tests for the others down the line.

Copy link
Contributor Author

@tannerdolby tannerdolby Jul 1, 2021

Choose a reason for hiding this comment

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

@connorjclark the above unit test should cover the fallback for nodeLabel when getNodeLabel() returns null, it could be a little more sturdy but let me know your thoughts.

Copy link
Collaborator

@connorjclark connorjclark Jul 1, 2021

Choose a reason for hiding this comment

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

The selector is the fallback now, not the tag name.

If you make a nested element, and give both of them a class and id, that should suffice for testing purposes.

(also, it's simpler to review if you just push your possible changes, as opposed to sharing snippets in comments)

Copy link
Contributor Author

@tannerdolby tannerdolby Jul 1, 2021

Choose a reason for hiding this comment

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

The selector is the fallback now, not the tag name.

I think my tests didn't fully illustrate that, will update with the suggested improvements.

(ok thanks for the heads up, I will make sure to avoid sharing snippets in comments in the future)

it('Returns selector as fallback if nodeLabel equals html tag name', () => {
// define a global `window` object for the first
// few lines in `getNodeDetails`
global.window = {};
Copy link
Collaborator

Choose a reason for hiding this comment

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

this (plus removing it) should be in the beforeAll/afterAll functions)

Copy link
Contributor Author

@tannerdolby tannerdolby Jul 1, 2021

Choose a reason for hiding this comment

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

added it to beforeAll/afterAll, this will definitely help in writing other getNodeDetail() tests as now there is a window variable in the global scope, nice!

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

thanks very much @tannerdolby for the contribution! this is great! 🎉

@tannerdolby
Copy link
Contributor Author

tannerdolby commented Jul 2, 2021

your welcome @patrickhulce ! I'm glad I was able to contribute 🎉 I appreciate @connorjclark's and your help/guidance along the way!

@tannerdolby tannerdolby requested a review from patrickhulce July 2, 2021 18:18
Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

fantastic work :)

@patrickhulce patrickhulce changed the title core: fallback to selector instead of tagName in nodeLabel generation core: fallback to selector, not tagName for nodeLabel Jul 2, 2021
@tannerdolby
Copy link
Contributor Author

tannerdolby commented Jul 2, 2021

thank you :) @patrickhulce ! it looks like some smoke tests are failing and expect a tagName instead of selector, let me know if there is anything else to finish up here.

and on a side note, do you think it would be worthwhile in a separate PR to write some more tests for getNodeDetails to make sure lhId, devToolsNodePath, and the other fields besides nodeLabel receive there expected values? Or since these helper functions used in details have their own describe blocks already, would it be redundant to add more tests that verify values already tested so to speak?

@patrickhulce
Copy link
Collaborator

it looks like some smoke tests are failing and expect a tagName instead of selector, let me know if there is anything else to finish up here.

Ah yeah, you're right those will need to be updated. It's fairly mechanical, just copy/paste the expected label into the expectations :)

@patrickhulce
Copy link
Collaborator

Thanks @tannerdolby! I think there are a few left

@tannerdolby
Copy link
Contributor Author

tannerdolby commented Jul 3, 2021

Your welcome @patrickhulce! Yeah it seems the the perf smoketest still has a few cases that need to be changed. Should have everything fixed up shortly.

@tannerdolby
Copy link
Contributor Author

dbw smoke test has one last expectation to fix

dbw smoketest complete.
  1 test(s) passing
  1 test(s) failing

@patrickhulce
Copy link
Collaborator

dbw smoke test has one last expectation to fix

That is actually a flaky test. We look good to go here, thank you @tannerdolby! :)

@patrickhulce patrickhulce merged commit 25cc9b6 into GoogleChrome:master Jul 6, 2021
@tannerdolby
Copy link
Contributor Author

Ok great! I'm happy to have been a part of this. Your welcome @patrickhulce! :)

@tannerdolby tannerdolby deleted the 12668-fallback-to-selector-in-node-label-generation branch July 6, 2021 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lighthouse doesn't tell which image doesn't have alt attribute
4 participants