From d6c8695c2cace59da0b70d6f42a089e22ae228b3 Mon Sep 17 00:00:00 2001 From: Sergey Pchelintsev <linz.sergey@gmail.com> Date: Wed, 29 Nov 2017 16:04:11 +0200 Subject: [PATCH] Remove nightwatch in favour of puppeteer --- .gitignore | 4 +-- .npmignore | 7 ++-- .travis.yml | 37 ++++----------------- README.md | 4 +-- e2e_helpers/assertions/assertBuffer.js | 45 -------------------------- e2e_helpers/commands/.gitkeep | 0 e2e_helpers/globals.js | 21 ------------ e2e_helpers/pages/helper.js | 25 -------------- example/index.js | 29 ++++++++--------- nightwatch.json | 44 ------------------------- package.json | 8 ++--- test/_open-page.js | 13 ++++++++ test/index.js | 26 +++++++++++++++ tests/00_sanity-check.js | 17 ---------- tests/01_basic-text.js | 13 -------- tests/02_multiline-text.js | 12 ------- tests/03_markup-text.js | 13 -------- 17 files changed, 70 insertions(+), 248 deletions(-) delete mode 100644 e2e_helpers/assertions/assertBuffer.js delete mode 100644 e2e_helpers/commands/.gitkeep delete mode 100644 e2e_helpers/globals.js delete mode 100644 e2e_helpers/pages/helper.js delete mode 100644 nightwatch.json create mode 100644 test/_open-page.js create mode 100644 test/index.js delete mode 100644 tests/00_sanity-check.js delete mode 100644 tests/01_basic-text.js delete mode 100644 tests/02_multiline-text.js delete mode 100644 tests/03_markup-text.js diff --git a/.gitignore b/.gitignore index a0b2031..009ebad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -node_modules +/node_modules .DS_Store reports -selenium-debug.log +/package-lock.json diff --git a/.npmignore b/.npmignore index ef5d2e3..bb66d28 100644 --- a/.npmignore +++ b/.npmignore @@ -1,5 +1,2 @@ -e2e_helpers -tests -nightwatch.json -selenium-debug.log -index.html \ No newline at end of file +test +index.html diff --git a/.travis.yml b/.travis.yml index 1864d97..4b1e0ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,33 +1,10 @@ language: node_js node_js: - - "4.2" - -env: - - E2E_BROWSER_VENDOR="internet explorer" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="internet explorer" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="MicrosoftEdge" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest-1" - - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest-1" - - E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest-1" - - E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest-1" - # TODO: add workaround for chromedriver issue - # - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest" - # - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest-1" - # TODO: look into execCommand(“copy”) support in Safari - # window.document.queryCommandSupported('copy') - false in 9.1.1 - # - E2E_BROWSER_VENDOR="safari" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest" - - E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest-1" - + - 8 +before_install: + - export DISPLAY=:99.0; + - sh -e /etc/init.d/xvfb start; addons: - sauce_connect: - username: "sudodoki" - access_key: - secure: "MBHn7+lxuJ0uNuFC8HjIZtosuOHICNW52fEhvtnJhXmaGOUXGLrQFUCvECJOoGrdOWmkiFaGgYINdF57HbYpyAICmv51UBlzHYftkTspYooH5+vni0ezPPpvxqNpUM/dlwfrdzC/ag97VYDeIxdYRKREwhRsNd5npE0Zrx1xmvzmnpdqdVhQ7Z/wQUDjv7talKC2fkaIYP+wEhVblnr18u0phFLqyADNsCV7D9QmILQWC4ieSz6ylTW9fb69B4rZElLj+D8qGvyvgmLnu+dK4Vlh0WuTdmVZ8TZS4OeBRIbjq/Mi2vMVuQLXz3DTiGWRZeDOBB5PYm/orgjgsnNg5hPx6t7yc4ypcBYf2gHxc31lV9VZRb10py33D8qPtcmPptwIWlsCQ4ANDyOwxck0FejMpjT+Ktkyme4nAvt9op289x8KKI0w8W7nHIB930lEookJCeMHWjyycPLJDTwYe60zBS24vNRF46ixhfpeO1zGw8nEj5qqSoEltunCOQ3Uvl25tNEuk9R649TyWbegjTuS4txqAsSjUnVMGvRBcZef4YyOQsggos1YbJMNnFSvDH9VaPYiJbg/qR7tb0YJ8gtAC9/6iqba6EZadkJQe9DHs6qu5zuoiwfSgBZTON2oWL6AGwySADm44SL7ikKJN8Zb8bLjQ1o15KinBVKLuOk=" - -script: - - REMOTE_SELENIUM=true npm test -- -e saucelabs + apt: + packages: + - xsel diff --git a/README.md b/README.md index cc6a606..3d52056 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ copy('Text', { Works everywhere where `prompt`* is available. Works best (i.e. without additional keystrokes) in Chrome, FF, Safari 10+, and, supposedly, IE/Edge. -Note: **does not work on some older iOS devices.** +Note: **does not work on some older iOS devices.** `*` – even though **Safari 8** has `prompt`, you cannot specify prefilled content for prompt modal – thus it **doesn't work** as expected. # Installation @@ -56,7 +56,7 @@ You will have `window.copyToClipboard` exposed for you to use. + [April 2015 update on Cut and Copy Commands](http://updates.html5rocks.com/2015/04/cut-and-copy-commands) # Running Tests -This project has some automated tests, that will run using [nightwatch](nightwatchjs.org) on top of [selenium](http://www.seleniumhq.org/). +This project has some automated tests, that will run using [ava](https://github.com/avajs/ava) on top of [puppeteer](https://github.com/GoogleChrome/puppeteer). ``` npm i diff --git a/e2e_helpers/assertions/assertBuffer.js b/e2e_helpers/assertions/assertBuffer.js deleted file mode 100644 index 65e642c..0000000 --- a/e2e_helpers/assertions/assertBuffer.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; -const util = require('util'); -const os = require('os'); - -const modificatorKey = (() => { - const usesCommandKey = () => - (process.env.REMOTE_SELENIUM - ? (process.env.E2E_PLATFORM || '').match(/os\sx/i) - : os.type().toLowerCase() === 'darwin') - - return usesCommandKey() - ? 'COMMAND' - : 'CONTROL'; -})() - -exports.assertion = function(expected) { - this.message = "Checking buffer contents"; - this.expected = (expected instanceof RegExp) ? "to match " + expected : expected; - - this.pass = function(value) { - return (expected instanceof RegExp) - ? expected.test(value) - : value === expected - }; - - this.value = function(value) { - return value; - }; - // TODO: generate element instead of using eisting one? - this.command = function(callback) { - return this.api - .url(this.api.launchUrl) - .waitForElementVisible('[data-test="placeholder"]', 500) - .click('[data-test="placeholder"]') - // This is not going to work in Chromedriver on Mac — https://bugs.chromium.org/p/chromedriver/issues/detail?id=30 - .keys([this.api.Keys[modificatorKey], 'v']) - .pause(10) - .keys(this.api.Keys[modificatorKey]) - .pause(10) - .getValue('[data-test="placeholder"]', function(result) { - callback(result.value) - }); - }; - -}; diff --git a/e2e_helpers/commands/.gitkeep b/e2e_helpers/commands/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/e2e_helpers/globals.js b/e2e_helpers/globals.js deleted file mode 100644 index 3d1b127..0000000 --- a/e2e_helpers/globals.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; -const http = require('http') -const nodeStatic = require('node-static'); -const fileServer = new nodeStatic.Server('./example'); -let server; -module.exports = { - before: function (next) { - console.log('Server started'); - server = http.createServer(function (request, response) { - request.addListener('end', function () { - fileServer.serve(request, response); - }).resume(); - }).listen(8080); - - next() - }, - after: function (next) { - server.close(); - next() - } -} diff --git a/e2e_helpers/pages/helper.js b/e2e_helpers/pages/helper.js deleted file mode 100644 index 33afc35..0000000 --- a/e2e_helpers/pages/helper.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; -const os = require('os'); -const modificatorKey = (os.type().toLowerCase() === 'darwin') - ? 'COMMAND' - : 'CONTROL'; - -module.exports = function(browser) { - return { - resetBuffer: function (text) { - return browser - .url(browser.launchUrl) - .waitForElementVisible('[data-test="placeholder"]', 500) - .click('[data-test="placeholder"]') - .keys(text || "some text to reset the clipboard") - .pause(10) - .keys([browser.Keys[modificatorKey], 'a']) - .keys(browser.Keys[modificatorKey]) - .pause(10) - .keys([browser.Keys[modificatorKey], 'c']) - .keys(browser.Keys[modificatorKey]) - .keys(browser.Keys.DELETE) - .pause(10); - } - } -} diff --git a/example/index.js b/example/index.js index 860068d..8fd8f00 100644 --- a/example/index.js +++ b/example/index.js @@ -20,21 +20,21 @@ function copy(text, options) { range = document.createRange(); selection = document.getSelection(); - mark = document.createElement('mark'); + mark = document.createElement('span'); mark.textContent = text; - mark.setAttribute('style', [ - // prevents scrolling to the end of the page - 'position: fixed', - 'top: 0', - 'clip: rect(0, 0, 0, 0)', - // used to preserve spaces and line breaks - 'white-space: pre', - // do not inherit user-select (it may be `none`) - '-webkit-user-select: text', - '-moz-user-select: text', - '-ms-user-select: text', - 'user-select: text', - ].join(';')); + // reset user styles for span element + mark.style.all = 'unset'; + // prevents scrolling to the end of the page + mark.style.position = 'fixed'; + mark.style.top = 0; + mark.style.clip = 'rect(0, 0, 0, 0)'; + // used to preserve spaces and line breaks + mark.style.whiteSpace = 'pre'; + // do not inherit user-select (it may be `none`) + mark.style.webkitUserSelect = 'text'; + mark.style.MozUserSelect = 'text'; + mark.style.msUserSelect = 'text'; + mark.style.userSelect = 'text'; document.body.appendChild(mark); @@ -79,7 +79,6 @@ function copy(text, options) { module.exports = copy; },{"toggle-selection":2}],2:[function(require,module,exports){ -var module = module || {}; module.exports = function () { var selection = document.getSelection(); diff --git a/nightwatch.json b/nightwatch.json deleted file mode 100644 index e343394..0000000 --- a/nightwatch.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "src_folders" : ["tests"], - "output_folder" : "reports", - "page_objects_path": "e2e_helpers/pages", - "custom_commands_path" : "e2e_helpers/commands", - "custom_assertions_path" : "e2e_helpers/assertions", - "globals_path" : "e2e_helpers/globals.js", - "selenium" : { - "start_process" : true, - "server_path" : "./node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.53.0.jar", - "log_path" : "", - "host" : "127.0.0.1", - "port" : 4444, - "cli_args" : { - "webdriver.chrome.driver" : "", - "webdriver.ie.driver" : "" - } - }, - "test_settings" : { - "default" : { - "launch_url" : "http://localhost:8080", - "selenium_port" : 4444, - "selenium_host" : "localhost", - "silent": true, - "screenshots" : { - "enabled" : true, - "path" : "reports" - } - }, - "saucelabs" : { - "selenium_host": "ondemand.saucelabs.com", - "selenium_port": 80, - "username" : "${SAUCE_USERNAME}", - "access_key" : "${SAUCE_ACCESS_KEY}", - "desiredCapabilities": { - "name": "test-firefox", - "browserName": "${E2E_BROWSER_VENDOR}", - "platform": "${E2E_PLATFORM}", - "version": "${E2E_BROWSER_VERSION}", - "tunnel-identifier": "${TRAVIS_JOB_NUMBER}" - } - } - } -} diff --git a/package.json b/package.json index fdb25f5..0c836a6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "types": "index.d.ts", "scripts": { "pretest": "browserify ./index.js -o ./example/index.js --standalone copyToClipboard", - "test": "nightwatch" + "test": "ava" }, "keywords": [ "clipboard", @@ -32,9 +32,9 @@ "example": "example" }, "devDependencies": { + "ava": "^0.24.0", "browserify": "^13.0.1", - "nightwatch": "^0.9.1", - "node-static": "^0.7.7", - "selenium-server-standalone-jar": "2.53.0" + "clipboardy": "^1.2.2", + "puppeteer": "^0.13.0" } } diff --git a/test/_open-page.js b/test/_open-page.js new file mode 100644 index 0000000..39396e9 --- /dev/null +++ b/test/_open-page.js @@ -0,0 +1,13 @@ +const puppeteer = require('puppeteer'); +const path = require('path'); + +let browser; + +module.exports = async () => { + if(!browser) { + browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--allow-no-sandbox-job'] }); + } + let page = await browser.newPage(); + await page.goto(`file://${path.resolve(__dirname, '../example/index.html')}`); + return page; +} diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..a930f31 --- /dev/null +++ b/test/index.js @@ -0,0 +1,26 @@ +const openPage = require('./_open-page'); +const test = require('ava').serial; +const clipboardy = require('clipboardy'); + +test('Sanity check', async t => { + let page = await openPage(); + t.is(await page.$eval('[data-test="heading"]', el => el.innerText), 'copy-to-clipboard Repo'); +}); + +test('Basic Text Copy', async t => { + let page = await openPage(); + await page.click('[data-test="init-basic-text"]'); + t.is(await clipboardy.read(), "Hello, I'm new content from your clipboard"); +}); + +test('Multiline Text Copy', async t => { + let page = await openPage(); + await page.click('[data-test="init-multiline-text"]'); + t.is(await clipboardy.read(), "This would be\nsome multiline text\nfor us to copy"); +}); + +test('Text w/ Markup Copy', async t => { + let page = await openPage(); + await page.click('[data-test="init-markup-text"]'); + t.is(await clipboardy.read(), "<script>\n alert\('this is some script'\)\n</script>"); +}); diff --git a/tests/00_sanity-check.js b/tests/00_sanity-check.js deleted file mode 100644 index 5d17ef3..0000000 --- a/tests/00_sanity-check.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; -module.exports = { - 'Sanity check' : function (browser) { - browser - .url(browser.launchUrl) - // uncomment for debug purposes - // .getLogTypes(function(result) { - // console.log(result); - // }) - // .getLog('browser', function(result) { - // console.log(result); - // }) - .waitForElementVisible('body', 1000) - .assert.containsText('[data-test="heading"]', 'copy-to-clipboard Repo') - .end(); - } -}; diff --git a/tests/01_basic-text.js b/tests/01_basic-text.js deleted file mode 100644 index c1103cf..0000000 --- a/tests/01_basic-text.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; -// is it better to use before/after to reset buffer? -module.exports = { - 'Basic Text Copy' : function (browser) { - browser - .page.helper().resetBuffer() - .url(browser.launchUrl) - .waitForElementVisible('[data-test="init-basic-text"]', 1000) - .click('[data-test="init-basic-text"]') - .assert.assertBuffer("Hello, I'm new content from your clipboard") - .end(); - } -}; diff --git a/tests/02_multiline-text.js b/tests/02_multiline-text.js deleted file mode 100644 index 0dc1f74..0000000 --- a/tests/02_multiline-text.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; -module.exports = { - 'Multiline Text Copy' : function (browser) { - browser - .page.helper().resetBuffer() - .url(browser.launchUrl) - .waitForElementVisible('[data-test="init-multiline-text"]', 1000) - .click('[data-test="init-multiline-text"]') - .assert.assertBuffer("This would be\nsome multiline text\nfor us to copy") - .end(); - } -}; diff --git a/tests/03_markup-text.js b/tests/03_markup-text.js deleted file mode 100644 index 3f2b512..0000000 --- a/tests/03_markup-text.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; -module.exports = { - 'Text w/ Markup Copy' : function (browser) { - browser - .page.helper().resetBuffer() - .url(browser.launchUrl) - .waitForElementVisible('[data-test="init-markup-text"]', 1000) - .click('[data-test="init-markup-text"]') - // using regexp instead of actual match because of chrome issue - .assert.assertBuffer(/<script>\n\s+alert\('this is some script'\)\n<\/script>\n*/m) - .end(); - } -};