-
Notifications
You must be signed in to change notification settings - Fork 334
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 button shim and setup Puppeteer #572
Conversation
src/components/button/button.js
Outdated
}, | ||
|
||
init: function () { | ||
var buttons = document.querySelectorAll('[role="button"]') |
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 will only work for buttons that are present on document ready, not buttons that are loaded in afterwards (e.g. via an AJAX request). This would be a 'regression' from what we've got in Frontend Toolkit, where we use a delegated event handler.
This might be OK, but we might want to consider:
- documenting this limitation
- allow
init
to be run more than once (i.e. ensure we only ever bind to the buttons that we haven't already handled)?
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 believe jQuery uses global document event handling to work around this.
e.g.
document.addEventListener('click', event => {
if (event.target === rolebutton) {
}
})
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.
@36degrees yep, it's something that I'm looking into.
I was thinking that we can either reinitialise on DOMContentLoaded
on document
addEvent(document, 'DOMContentLoaded', init)
or watch for the keydown
event at the document level as @NickColley described.
src/components/button/button.js
Outdated
@@ -0,0 +1,70 @@ | |||
// javascript 'shim' to trigger the click event of element(s) |
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.
Being a little bit fussy here, but can take this opportunity to wrap comments consistently and use the proper capitalisation?
src/components/button/button.js
Outdated
|
||
eventHandler: function (event) { | ||
// if the keyCode (which) is 32 it's a space, let's simulate a click. | ||
if (GOVUK_FRONTEND.buttons.charCode(event) === 32) { |
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.
Would be good to copy what we've got in the details polyfill and make the space character code a constant.
src/components/button/button.js
Outdated
global.GOVUK_FRONTEND = GOVUK_FRONTEND | ||
|
||
// auto-initialise | ||
GOVUK_FRONTEND.buttons.init() |
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.
If we're immediately initialising, and this JS only binds to buttons present at the time the script loads, am I right in thinking we're then relying on the user including this JS at the end of their body, rather than in the <head>
? That seems like it might be quite fragile in use.
Should we either run init on document ready, or use a delegated event handler?
package.json
Outdated
@@ -22,7 +22,8 @@ | |||
"build:dist": "node bin/check-nvmrc.js && gulp build:dist --destination 'dist' && npm run test:build:dist", | |||
"test": "standard && gulp test && npm run test:app && npm run test:components && npm run test:generate:readme", | |||
"test:app": "jest app/__tests__/app.test.js --forceExit # express server fails to end process", | |||
"test:components": "jest src/", | |||
"test:components": "jest src/**/template.test.js --env=jsdom", | |||
"test:components:integration": "jest src/button/button.test.js", |
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.
how are we going to scale that to multiple components?
I get 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.
Have we looked into expect-puppeteer
at all? Looks like we could use it to expect a click rather than relying on side effects (the page location changing)
lib/puppeteer_environment.js
Outdated
|
||
const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup') | ||
|
||
class PuppeteerEnvironment extends NodeEnvironment { |
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.
Would be really good to get some comments throughout this file, especially in the setup function.
lib/puppeteer_environment.js
Outdated
|
||
class PuppeteerEnvironment extends NodeEnvironment { | ||
async setup () { | ||
console.log(chalk.yellow('Setup Test Environment.')) |
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.
Are these comments still useful, or should they be removed now?
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.
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.
Happy to keep them in if they are useful :)
lib/puppeteer_environment.js
Outdated
await super.teardown() | ||
} | ||
|
||
runScript (script) { |
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.
Do we need to define this function if all we're doing is calling the parent method? Does it not just inherit it?
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.
It's not being used now, but gives the space to allowing extra code before running the script. Can remove.
lib/puppeteer_setup.js
Outdated
|
||
module.exports = async function () { | ||
console.log(chalk.green('Setup Puppeteer')) | ||
const browser = await puppeteer.launch({args: ['--no-sandbox']}) |
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.
Again, comments here would be good. For example, what is --no-sandbox
doing? Why is it needed?
src/button/button.js
Outdated
} | ||
}, | ||
|
||
eventHandler: function (e) { |
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.
Would be ace to document this in the same way the other functions are documented.
@@ -0,0 +1,85 @@ | |||
/** | |||
* JavaScript 'shim' to trigger the click event of element(s) when the space key is pressed. |
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.
Comments in this file are generally 💯. Is the doc block style new? Are there new conventions we're establishing that need to be documented?
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.
We started using them on the lib jest helpers, seems like a good thing to try to do everywhere it makes sense.
src/button/button.test.js
Outdated
|
||
const href = await page.evaluate(() => document.body.getElementsByTagName('a')[0].getAttribute('href')) | ||
|
||
await page.keyboard.press('Tab') |
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.
Would it be clearer / more explicit to use page.focus('a')
here?
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.
Sure. I was replicating my manual testing, but it makes sense to use focus for this.
@igloosi the server wasn't synchronised with puppeteer. last commit fixes that. |
@36degrees no we haven't looked into it since this PR doesn't rely on |
6b30a15
to
d30e84e
Compare
d30e84e
to
50c3c38
Compare
50c3c38
to
2b5541d
Compare
2b5541d
to
848c289
Compare
848c289
to
ffb7bc2
Compare
ffb7bc2
to
b0041eb
Compare
b0041eb
to
1cf7827
Compare
.travis.yml
Outdated
language: node_js | ||
node_js: |
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.
See if we can remove these changes and see if it still works?
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.
sure thing. updated. works as expected.
1cf7827
to
4018c2d
Compare
4018c2d
to
3119acd
Compare
Thanks everyone for feedback. I tried to discuss every comment online or offline. |
This PR:
addEvent
,preventDefault
). this functions would ideally sit in acommon.js
/core.js
/lib.js
that any component can reference.Manual tests
Browsers
AT testing
Automated tests
Background on why we need this shim
For links that have role="button" we need to add an event handler so that it can be activated with the space bar alphagov/govuk_elements#272 (comment)
Notes to reviewer(s)
Left the commits separated so we can compare the govuk-frontend shim with the govuk_frontend_toolkit one.
Trello card