-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
core: fallback to selector, not tagName for nodeLabel #12727
Conversation
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 What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
@googlebot I signed it! |
Oh I see why the "pr title lint" failed, there is an expected PR title format |
@@ -400,6 +400,7 @@ function getNodeLabel(element) { | |||
} | |||
|
|||
const tagName = element.tagName.toLowerCase(); | |||
const selector = getNodeSelector(element); |
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.
two options here to avoid calling getNodeSelector
twice per call to getNodeDetails
:
- have this function return null if no useful label, and use result of
getNodeSelector
as fallback ingetNodeDetails
(getNodeLabel(...) || selector
) - have
getNodeSelector
accept adefault
parameter and return that as default
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.
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.
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.
also you'll likely need to fix the tests (run yarn jest page-functions
)
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.
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', () => { |
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 add a test case to getNodeDetails
that covers the fallack?
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.
Yes! That's where my mind skipped, thank you, will commit change shortly :)
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.
@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()
?
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.
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.
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.
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
.
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.
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.
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.
@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.
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.
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)
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.
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 = {}; |
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.
this (plus removing it) should be in the beforeAll/afterAll functions)
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.
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!
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.
thanks very much @tannerdolby for the contribution! this is great! 🎉
your welcome @patrickhulce ! I'm glad I was able to contribute 🎉 I appreciate @connorjclark's and your help/guidance along the way! |
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.
fantastic work :)
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 |
Ah yeah, you're right those will need to be updated. It's fairly mechanical, just copy/paste the expected label into the expectations :) |
Thanks @tannerdolby! I think there are a few left |
Your welcome @patrickhulce! Yeah it seems the the |
|
That is actually a flaky test. We look good to go here, thank you @tannerdolby! :) |
Ok great! I'm happy to have been a part of this. Your welcome @patrickhulce! :) |
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:
yarn
andyarn build-all
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 fallbackselector
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