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 button shim and setup Puppeteer #572

Merged
merged 6 commits into from
Mar 14, 2018
Merged

Add button shim and setup Puppeteer #572

merged 6 commits into from
Mar 14, 2018

Conversation

alex-ju
Copy link
Contributor

@alex-ju alex-ju commented Mar 5, 2018

This PR:

  • adds shim-links-with-button-role.js from govuk_frontend_toolkit
  • rewrites the code in plain javascript
  • updates the code to use common/generic functions (to deal with polyfill; e.g. addEvent, preventDefault). this functions would ideally sit in a common.js/core.js/lib.js that any component can reference.
  • sets up Puppeteer for integration testing and add tests to make sure the shim works in the browser

Manual tests
Browsers

  • IE8+
  • Latest Safari, Chrome, Firefox, Edge

AT testing

  • VoiceOver
  • JAWS
  • NDVA
  • Dragon

Automated tests

  • Jest integration tests written

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

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 5, 2018 13:30 Inactive
@alex-ju alex-ju changed the title WIP: Add button shim [WIP] Add button shim Mar 5, 2018
},

init: function () {
var buttons = document.querySelectorAll('[role="button"]')
Copy link
Contributor

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)?

Copy link
Contributor

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) {
  }
})

Copy link
Contributor Author

@alex-ju alex-ju Mar 5, 2018

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.

@@ -0,0 +1,70 @@
// javascript 'shim' to trigger the click event of element(s)
Copy link
Contributor

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?


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) {
Copy link
Contributor

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.

global.GOVUK_FRONTEND = GOVUK_FRONTEND

// auto-initialise
GOVUK_FRONTEND.buttons.init()
Copy link
Contributor

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?

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 5, 2018 14:53 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 5, 2018 15:41 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 5, 2018 16:14 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 7, 2018 14:46 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 7, 2018 14:47 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 8, 2018 10:47 Inactive
@alex-ju alex-ju changed the title [WIP] Add button shim Add button shim Mar 8, 2018
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",
Copy link

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?

@kr8n3r
Copy link

kr8n3r commented Mar 8, 2018

I get this

 FAIL  src/button/button.test.js
  /components/button
    /components/button/link
      ✕ renders a link button (15ms)
      ✕ triggers the click event when the space key is pressed (9ms)

  ● /components/button › /components/button/link › renders a link button

    net::ERR_CONNECTION_REFUSED

      at navigate (node_modules/puppeteer/lib/Page.js:520:37)

  ● /components/button › /components/button/link › triggers the click event when the space key is pressed

    Protocol error (Runtime.callFunctionOn): Cannot find context with specified idundefined

      at Promise (node_modules/puppeteer/lib/Connection.js:196:56)
      at CDPSession.send (node_modules/puppeteer/lib/Connection.js:195:12)
      at ExecutionContext.evaluateHandle (node_modules/puppeteer/lib/ExecutionContext.js:67:75)
      at ExecutionContext.evaluate (node_modules/puppeteer/lib/ExecutionContext.js:46:31)
      at Frame.evaluate (node_modules/puppeteer/lib/FrameManager.js:299:20)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 total
Snapshots:   0 total
Time:        1.084s
Ran all test suites matching /src\/button\/button.test.js/i.
Teardown Puppeteer
Teardown Test Environment.

@alex-ju alex-ju changed the title Add button shim [DNM] Add button shim Mar 8, 2018
Copy link
Contributor

@36degrees 36degrees left a 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)


const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup')

class PuppeteerEnvironment extends NodeEnvironment {
Copy link
Contributor

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.


class PuppeteerEnvironment extends NodeEnvironment {
async setup () {
console.log(chalk.yellow('Setup Test Environment.'))
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought would be good to know what happens and when.
screen shot 2018-03-08 at 15 08 58
Can remove them all.

Copy link
Contributor

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 :)

await super.teardown()
}

runScript (script) {
Copy link
Contributor

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?

Copy link
Contributor Author

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.


module.exports = async function () {
console.log(chalk.green('Setup Puppeteer'))
const browser = await puppeteer.launch({args: ['--no-sandbox']})
Copy link
Contributor

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?

}
},

eventHandler: function (e) {
Copy link
Contributor

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.
Copy link
Contributor

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?

Copy link
Contributor

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.


const href = await page.evaluate(() => document.body.getElementsByTagName('a')[0].getAttribute('href'))

await page.keyboard.press('Tab')
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 8, 2018 14:47 Inactive
@alex-ju alex-ju changed the title [DNM] Add button shim Add button shim and setup Puppeteer Mar 8, 2018
@alex-ju
Copy link
Contributor Author

alex-ju commented Mar 8, 2018

@igloosi the server wasn't synchronised with puppeteer. last commit fixes that.

@alex-ju
Copy link
Contributor Author

alex-ju commented Mar 8, 2018

@36degrees no we haven't looked into it since this PR doesn't rely on expect-puppeteer or jest-puppeteer as a dependency. we only use puppeteer, so the documentation that I've been looking at was GoogleChrome/puppeteer. if we want to, we can change dependencies, rely on jest-puppeteer and update the tests accordingly.

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 8, 2018 15:04 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 8, 2018 15:08 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 8, 2018 15:13 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 12, 2018 17:31 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 13, 2018 08:51 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 13, 2018 09:04 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 13, 2018 09:11 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 13, 2018 09:22 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 13, 2018 09:34 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 13, 2018 11:58 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 14, 2018 09:49 Inactive
@alex-ju alex-ju changed the title [WIP] Add button shim and setup Puppeteer Add button shim and setup Puppeteer Mar 14, 2018
.travis.yml Outdated
language: node_js
node_js:
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-572 March 14, 2018 12:59 Inactive
@alex-ju
Copy link
Contributor Author

alex-ju commented Mar 14, 2018

Thanks everyone for feedback. I tried to discuss every comment online or offline.
It's now updated and ready for review.

@alex-ju alex-ju merged commit a7488f7 into master Mar 14, 2018
@alex-ju alex-ju deleted the add-button-shim branch March 14, 2018 19:35
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.

6 participants