From 6b03c3b6134bb0b063fa5895012f8b332395f1c6 Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Fri, 15 Dec 2017 16:34:16 -0600 Subject: [PATCH 1/4] Fixes #1986 - Start migration to Intern 4 --- package.json | 4 +- tests/.eslintrc | 5 ++ tests/functional-all.js | 38 -------- tests/functional-nonauth.js | 29 ------- tests/intern.js | 86 ------------------- tests/javascript/functional/test.js | 18 ++++ .../old}/comments-auth.js | 0 .../old}/comments-non-auth.js | 0 .../old}/contributors-non-auth.js | 0 .../old}/history-navigation-non-auth.js | 0 .../old}/image-uploads-non-auth.js | 0 .../old}/index-non-auth.js | 0 .../old}/issue-list-non-auth.js | 0 .../old}/issues-auth.js | 0 .../old}/issues-non-auth.js | 0 .../old}/labels-auth.js | 0 .../old}/lib/helpers.js | 0 .../old}/lib/window-helpers.js | 0 .../old}/milestones-auth.js | 0 .../old}/milestones-non-auth.js | 0 .../old}/new-issue-non-auth.js | 0 .../old}/reporting-auth.js | 0 .../old}/reporting-non-auth.js | 0 .../old}/search-auth.js | 0 .../old}/search-non-auth.js | 0 .../old}/user-activity-auth.js | 0 .../old}/user-activity-non-auth.js | 0 tests/{ => python}/__init__.py | 0 tests/{ => python}/test_api_urls.py | 0 tests/{ => python}/test_dashboard.py | 0 tests/{ => python}/test_form.py | 0 tests/{ => python}/test_helpers.py | 0 tests/{ => python}/test_http_caching.py | 0 tests/{ => python}/test_rendering.py | 0 tests/{ => python}/test_topsites.py | 0 tests/{ => python}/test_uploads.py | 0 tests/{ => python}/test_urls.py | 0 tests/{ => python}/test_webhook.py | 0 38 files changed, 25 insertions(+), 155 deletions(-) create mode 100644 tests/.eslintrc delete mode 100644 tests/functional-all.js delete mode 100644 tests/functional-nonauth.js delete mode 100644 tests/intern.js create mode 100644 tests/javascript/functional/test.js rename tests/{functional => javascript/old}/comments-auth.js (100%) rename tests/{functional => javascript/old}/comments-non-auth.js (100%) rename tests/{functional => javascript/old}/contributors-non-auth.js (100%) rename tests/{functional => javascript/old}/history-navigation-non-auth.js (100%) rename tests/{functional => javascript/old}/image-uploads-non-auth.js (100%) rename tests/{functional => javascript/old}/index-non-auth.js (100%) rename tests/{functional => javascript/old}/issue-list-non-auth.js (100%) rename tests/{functional => javascript/old}/issues-auth.js (100%) rename tests/{functional => javascript/old}/issues-non-auth.js (100%) rename tests/{functional => javascript/old}/labels-auth.js (100%) rename tests/{functional => javascript/old}/lib/helpers.js (100%) rename tests/{functional => javascript/old}/lib/window-helpers.js (100%) rename tests/{functional => javascript/old}/milestones-auth.js (100%) rename tests/{functional => javascript/old}/milestones-non-auth.js (100%) rename tests/{functional => javascript/old}/new-issue-non-auth.js (100%) rename tests/{functional => javascript/old}/reporting-auth.js (100%) rename tests/{functional => javascript/old}/reporting-non-auth.js (100%) rename tests/{functional => javascript/old}/search-auth.js (100%) rename tests/{functional => javascript/old}/search-non-auth.js (100%) rename tests/{functional => javascript/old}/user-activity-auth.js (100%) rename tests/{functional => javascript/old}/user-activity-non-auth.js (100%) rename tests/{ => python}/__init__.py (100%) rename tests/{ => python}/test_api_urls.py (100%) rename tests/{ => python}/test_dashboard.py (100%) rename tests/{ => python}/test_form.py (100%) rename tests/{ => python}/test_helpers.py (100%) rename tests/{ => python}/test_http_caching.py (100%) rename tests/{ => python}/test_rendering.py (100%) rename tests/{ => python}/test_topsites.py (100%) rename tests/{ => python}/test_uploads.py (100%) rename tests/{ => python}/test_urls.py (100%) rename tests/{ => python}/test_webhook.py (100%) diff --git a/package.json b/package.json index 1dbf52e01..f675d5021 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,4 @@ -{ + { "title": "webcompat.com", "name": "webcompat", "description": "The webcompat.com is a tool to gather web compatibility bugs, inform the community and help to fix the web.", @@ -37,7 +37,7 @@ "grunt-contrib-watch": "^1.0.0", "grunt-postcss": "^0.8.0", "husky": "^0.13.4", - "intern": "^3.4.6", + "intern": "^4.1.4", "lint-staged": "^3.6.1", "load-grunt-tasks": "^3.5.2", "postcss": "^5.2.17", diff --git a/tests/.eslintrc b/tests/.eslintrc new file mode 100644 index 000000000..95884cb22 --- /dev/null +++ b/tests/.eslintrc @@ -0,0 +1,5 @@ +{ + "globals": { + "intern": true + } +} diff --git a/tests/functional-all.js b/tests/functional-all.js deleted file mode 100644 index 97c77ec7d..000000000 --- a/tests/functional-all.js +++ /dev/null @@ -1,38 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -To run a single test suite, use the following from the project root. - -node_modules/.bin/intern-runner config=tests/intern \ - functionalSuites=tests/functional/foo.js \ - user="github_username" \ - pw="github_password" -*/ - -define( - [ - "./functional/reporting-non-auth.js", - "./functional/comments-non-auth.js", - "./functional/contributors-non-auth.js", - "./functional/comments-auth.js", - "./functional/history-navigation-non-auth.js", - "./functional/image-uploads-non-auth.js", - "./functional/index-non-auth.js", - "./functional/issue-list-non-auth.js", - "./functional/issues-non-auth.js", - "./functional/new-issue-non-auth.js", - "./functional/search-non-auth.js", - "./functional/search-auth.js", - "./functional/issues-auth.js", - "./functional/labels-auth.js", - "./functional/milestones-auth.js", - "./functional/reporting-auth.js", - "./functional/user-activity-auth.js", - "./functional/user-activity-non-auth.js" - ], - function() { - "use strict"; - } -); diff --git a/tests/functional-nonauth.js b/tests/functional-nonauth.js deleted file mode 100644 index 661c976d4..000000000 --- a/tests/functional-nonauth.js +++ /dev/null @@ -1,29 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -This file is provided so we can run tests on Travis for pull requests -from forks that don't have access to encrypted environment variables. - -node_modules/.bin/intern-runner config=tests/intern \ - functionalSuites=tests/functional-nonauth -*/ - -define( - [ - "./functional/reporting-non-auth.js", - "./functional/comments-non-auth.js", - "./functional/contributors-non-auth.js", - "./functional/history-navigation-non-auth.js", - "./functional/image-uploads-non-auth.js", - "./functional/index-non-auth.js", - "./functional/issue-list-non-auth.js", - "./functional/issues-non-auth.js", - "./functional/new-issue-non-auth.js", - "./functional/search-non-auth.js" - ], - function() { - "use strict"; - } -); diff --git a/tests/intern.js b/tests/intern.js deleted file mode 100644 index e681fe65a..000000000 --- a/tests/intern.js +++ /dev/null @@ -1,86 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Learn more about configuring this file at . -// These default settings work OK for most people. The options that *must* be changed below are the -// packages, suites, excludeInstrumentation, and (if you want functional tests) functionalSuites. - -define(["intern"], function(intern) { - "use strict"; - var args = intern.args; - var siteRoot = args.siteRoot ? args.siteRoot : "http://localhost:5000"; - - var environments = []; - var browsers = args.browsers - ? args.browsers.replace(/\s/g, "").split(",") - : ["firefox"]; - - browsers.forEach(function(b) { - environments.push({ - browserName: b.toLowerCase(), - marionette: true - }); - }); - - return { - // Configuration object for webcompat - wc: { - pageLoadTimeout: args.wcPageLoadTimeout - ? parseInt(args.wcPageLoadTimeout, 10) - : 10000 - }, - - setup: function() { - define("FunctionalHelpers", ["tests/functional/lib/helpers"], function( - FunctionalHelpers - ) { - return { - checkServer: FunctionalHelpers.checkServer - }; - }); - var serverPromise; - require(["FunctionalHelpers"], function(FunctionalHelpers) { - serverPromise = FunctionalHelpers.checkServer(); - }); - return serverPromise; - }, - - // The port on which the instrumenting proxy will listen - proxyPort: 9090, - - // A fully qualified URL to the Intern proxy - proxyUrl: "http://127.0.0.1:9090/", - siteRoot: siteRoot, - tunnel: "SeleniumTunnel", - tunnelOptions: { - // this tells SeleniumTunnel to download geckodriver and chromedriver - drivers: ["firefox"], - // version of Selenium - version: "3.6.0" - }, - - // Only one browser at a time. Takes longer, but gets less intermittent errors. - maxConcurrency: 1, - - // Note: this is temporary until the fix for the following is released (should be Firefox 56): - // https://github.com/mozilla/geckodriver/issues/858. It can be removed then. - capabilities: { - "moz:firefoxOptions": { - prefs: { - "dom.file.createInChild": true - }, - args: ["-headless"] - } - }, - - environments: environments, - - filterErrorStack: true, - reporters: ["Pretty"], - - // Unless you pass in a command-line arg saying otherwise, we run all tests by default. - functionalSuites: ["tests/functional-all"], - excludeInstrumentation: true - }; -}); diff --git a/tests/javascript/functional/test.js b/tests/javascript/functional/test.js new file mode 100644 index 000000000..6340aee4c --- /dev/null +++ b/tests/javascript/functional/test.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const { registerSuite } = intern.getInterface("object"); +const { assert } = intern.getPlugin("chai"); + +registerSuite("Comments (non-auth)", { + whatever() { + return this.remote + .get("http://localhost:5000/issues/200") + .findByCssSelector(".js-Comment-form") + .then(assert.fail, function(err) { + assert.isTrue(/NoSuchElement/.test(String(err))); + }) + .end(); + } +}); diff --git a/tests/functional/comments-auth.js b/tests/javascript/old/comments-auth.js similarity index 100% rename from tests/functional/comments-auth.js rename to tests/javascript/old/comments-auth.js diff --git a/tests/functional/comments-non-auth.js b/tests/javascript/old/comments-non-auth.js similarity index 100% rename from tests/functional/comments-non-auth.js rename to tests/javascript/old/comments-non-auth.js diff --git a/tests/functional/contributors-non-auth.js b/tests/javascript/old/contributors-non-auth.js similarity index 100% rename from tests/functional/contributors-non-auth.js rename to tests/javascript/old/contributors-non-auth.js diff --git a/tests/functional/history-navigation-non-auth.js b/tests/javascript/old/history-navigation-non-auth.js similarity index 100% rename from tests/functional/history-navigation-non-auth.js rename to tests/javascript/old/history-navigation-non-auth.js diff --git a/tests/functional/image-uploads-non-auth.js b/tests/javascript/old/image-uploads-non-auth.js similarity index 100% rename from tests/functional/image-uploads-non-auth.js rename to tests/javascript/old/image-uploads-non-auth.js diff --git a/tests/functional/index-non-auth.js b/tests/javascript/old/index-non-auth.js similarity index 100% rename from tests/functional/index-non-auth.js rename to tests/javascript/old/index-non-auth.js diff --git a/tests/functional/issue-list-non-auth.js b/tests/javascript/old/issue-list-non-auth.js similarity index 100% rename from tests/functional/issue-list-non-auth.js rename to tests/javascript/old/issue-list-non-auth.js diff --git a/tests/functional/issues-auth.js b/tests/javascript/old/issues-auth.js similarity index 100% rename from tests/functional/issues-auth.js rename to tests/javascript/old/issues-auth.js diff --git a/tests/functional/issues-non-auth.js b/tests/javascript/old/issues-non-auth.js similarity index 100% rename from tests/functional/issues-non-auth.js rename to tests/javascript/old/issues-non-auth.js diff --git a/tests/functional/labels-auth.js b/tests/javascript/old/labels-auth.js similarity index 100% rename from tests/functional/labels-auth.js rename to tests/javascript/old/labels-auth.js diff --git a/tests/functional/lib/helpers.js b/tests/javascript/old/lib/helpers.js similarity index 100% rename from tests/functional/lib/helpers.js rename to tests/javascript/old/lib/helpers.js diff --git a/tests/functional/lib/window-helpers.js b/tests/javascript/old/lib/window-helpers.js similarity index 100% rename from tests/functional/lib/window-helpers.js rename to tests/javascript/old/lib/window-helpers.js diff --git a/tests/functional/milestones-auth.js b/tests/javascript/old/milestones-auth.js similarity index 100% rename from tests/functional/milestones-auth.js rename to tests/javascript/old/milestones-auth.js diff --git a/tests/functional/milestones-non-auth.js b/tests/javascript/old/milestones-non-auth.js similarity index 100% rename from tests/functional/milestones-non-auth.js rename to tests/javascript/old/milestones-non-auth.js diff --git a/tests/functional/new-issue-non-auth.js b/tests/javascript/old/new-issue-non-auth.js similarity index 100% rename from tests/functional/new-issue-non-auth.js rename to tests/javascript/old/new-issue-non-auth.js diff --git a/tests/functional/reporting-auth.js b/tests/javascript/old/reporting-auth.js similarity index 100% rename from tests/functional/reporting-auth.js rename to tests/javascript/old/reporting-auth.js diff --git a/tests/functional/reporting-non-auth.js b/tests/javascript/old/reporting-non-auth.js similarity index 100% rename from tests/functional/reporting-non-auth.js rename to tests/javascript/old/reporting-non-auth.js diff --git a/tests/functional/search-auth.js b/tests/javascript/old/search-auth.js similarity index 100% rename from tests/functional/search-auth.js rename to tests/javascript/old/search-auth.js diff --git a/tests/functional/search-non-auth.js b/tests/javascript/old/search-non-auth.js similarity index 100% rename from tests/functional/search-non-auth.js rename to tests/javascript/old/search-non-auth.js diff --git a/tests/functional/user-activity-auth.js b/tests/javascript/old/user-activity-auth.js similarity index 100% rename from tests/functional/user-activity-auth.js rename to tests/javascript/old/user-activity-auth.js diff --git a/tests/functional/user-activity-non-auth.js b/tests/javascript/old/user-activity-non-auth.js similarity index 100% rename from tests/functional/user-activity-non-auth.js rename to tests/javascript/old/user-activity-non-auth.js diff --git a/tests/__init__.py b/tests/python/__init__.py similarity index 100% rename from tests/__init__.py rename to tests/python/__init__.py diff --git a/tests/test_api_urls.py b/tests/python/test_api_urls.py similarity index 100% rename from tests/test_api_urls.py rename to tests/python/test_api_urls.py diff --git a/tests/test_dashboard.py b/tests/python/test_dashboard.py similarity index 100% rename from tests/test_dashboard.py rename to tests/python/test_dashboard.py diff --git a/tests/test_form.py b/tests/python/test_form.py similarity index 100% rename from tests/test_form.py rename to tests/python/test_form.py diff --git a/tests/test_helpers.py b/tests/python/test_helpers.py similarity index 100% rename from tests/test_helpers.py rename to tests/python/test_helpers.py diff --git a/tests/test_http_caching.py b/tests/python/test_http_caching.py similarity index 100% rename from tests/test_http_caching.py rename to tests/python/test_http_caching.py diff --git a/tests/test_rendering.py b/tests/python/test_rendering.py similarity index 100% rename from tests/test_rendering.py rename to tests/python/test_rendering.py diff --git a/tests/test_topsites.py b/tests/python/test_topsites.py similarity index 100% rename from tests/test_topsites.py rename to tests/python/test_topsites.py diff --git a/tests/test_uploads.py b/tests/python/test_uploads.py similarity index 100% rename from tests/test_uploads.py rename to tests/python/test_uploads.py diff --git a/tests/test_urls.py b/tests/python/test_urls.py similarity index 100% rename from tests/test_urls.py rename to tests/python/test_urls.py diff --git a/tests/test_webhook.py b/tests/python/test_webhook.py similarity index 100% rename from tests/test_webhook.py rename to tests/python/test_webhook.py From 30cd7fb48dd145bea4484a3c5a900b41da4a29d7 Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Sat, 13 Jan 2018 11:36:22 -0200 Subject: [PATCH 2/4] Fixes #1986 - Finishes migration to Intern 4. - Adds 'browsers' optional argument when running tests - Changes folder structure separating functional and unit tests completely - Also fixes #1977 and #1981. --- package.json | 5 +- tests/.eslintrc | 6 +- tests/functional/_intern.js | 68 +++ tests/functional/comments-auth.js | 147 ++++++ tests/functional/comments-non-auth.js | 25 + tests/functional/contributors-non-auth.js | 109 +++++ .../functional/history-navigation-non-auth.js | 41 ++ tests/functional/image-uploads-non-auth.js | 203 ++++++++ tests/functional/index-non-auth.js | 119 +++++ tests/functional/issue-list-non-auth.js | 447 +++++++++++++++++ tests/functional/issues-auth.js | 48 ++ tests/functional/issues-non-auth.js | 119 +++++ tests/functional/labels-auth.js | 111 +++++ tests/functional/lib/helpers.js | 55 +++ tests/functional/lib/setup.js | 62 +++ .../old => functional}/lib/window-helpers.js | 0 tests/functional/milestones-auth.js | 111 +++++ tests/functional/milestones-non-auth.js | 48 ++ tests/functional/new-issue-non-auth.js | 31 ++ tests/functional/reporting-auth.js | 38 ++ tests/functional/reporting-non-auth.js | 305 ++++++++++++ tests/functional/search-auth.js | 222 +++++++++ tests/functional/search-non-auth.js | 116 +++++ tests/functional/user-activity-auth.js | 105 ++++ tests/functional/user-activity-non-auth.js | 33 ++ tests/javascript/functional/test.js | 18 - tests/javascript/old/comments-auth.js | 154 ------ tests/javascript/old/comments-non-auth.js | 32 -- tests/javascript/old/contributors-non-auth.js | 116 ----- .../old/history-navigation-non-auth.js | 48 -- .../javascript/old/image-uploads-non-auth.js | 212 -------- tests/javascript/old/index-non-auth.js | 128 ----- tests/javascript/old/issue-list-non-auth.js | 452 ------------------ tests/javascript/old/issues-auth.js | 48 -- tests/javascript/old/issues-non-auth.js | 124 ----- tests/javascript/old/labels-auth.js | 121 ----- tests/javascript/old/lib/helpers.js | 111 ----- tests/javascript/old/milestones-auth.js | 121 ----- tests/javascript/old/milestones-non-auth.js | 57 --- tests/javascript/old/new-issue-non-auth.js | 38 -- tests/javascript/old/reporting-auth.js | 45 -- tests/javascript/old/reporting-non-auth.js | 329 ------------- tests/javascript/old/search-auth.js | 230 --------- tests/javascript/old/search-non-auth.js | 132 ----- tests/javascript/old/user-activity-auth.js | 112 ----- .../javascript/old/user-activity-non-auth.js | 40 -- tests/{python => unit}/__init__.py | 0 tests/{python => unit}/test_api_urls.py | 0 tests/{python => unit}/test_dashboard.py | 0 tests/{python => unit}/test_form.py | 0 tests/{python => unit}/test_helpers.py | 0 tests/{python => unit}/test_http_caching.py | 0 tests/{python => unit}/test_rendering.py | 0 tests/{python => unit}/test_topsites.py | 0 tests/{python => unit}/test_uploads.py | 0 tests/{python => unit}/test_urls.py | 0 tests/{python => unit}/test_webhook.py | 0 57 files changed, 2571 insertions(+), 2671 deletions(-) create mode 100644 tests/functional/_intern.js create mode 100755 tests/functional/comments-auth.js create mode 100755 tests/functional/comments-non-auth.js create mode 100755 tests/functional/contributors-non-auth.js create mode 100755 tests/functional/history-navigation-non-auth.js create mode 100755 tests/functional/image-uploads-non-auth.js create mode 100755 tests/functional/index-non-auth.js create mode 100755 tests/functional/issue-list-non-auth.js create mode 100755 tests/functional/issues-auth.js create mode 100755 tests/functional/issues-non-auth.js create mode 100755 tests/functional/labels-auth.js create mode 100644 tests/functional/lib/helpers.js create mode 100644 tests/functional/lib/setup.js rename tests/{javascript/old => functional}/lib/window-helpers.js (100%) create mode 100755 tests/functional/milestones-auth.js create mode 100755 tests/functional/milestones-non-auth.js create mode 100755 tests/functional/new-issue-non-auth.js create mode 100755 tests/functional/reporting-auth.js create mode 100755 tests/functional/reporting-non-auth.js create mode 100755 tests/functional/search-auth.js create mode 100755 tests/functional/search-non-auth.js create mode 100755 tests/functional/user-activity-auth.js create mode 100755 tests/functional/user-activity-non-auth.js delete mode 100644 tests/javascript/functional/test.js delete mode 100644 tests/javascript/old/comments-auth.js delete mode 100644 tests/javascript/old/comments-non-auth.js delete mode 100644 tests/javascript/old/contributors-non-auth.js delete mode 100644 tests/javascript/old/history-navigation-non-auth.js delete mode 100644 tests/javascript/old/image-uploads-non-auth.js delete mode 100644 tests/javascript/old/index-non-auth.js delete mode 100644 tests/javascript/old/issue-list-non-auth.js delete mode 100644 tests/javascript/old/issues-auth.js delete mode 100644 tests/javascript/old/issues-non-auth.js delete mode 100644 tests/javascript/old/labels-auth.js delete mode 100644 tests/javascript/old/lib/helpers.js delete mode 100644 tests/javascript/old/milestones-auth.js delete mode 100644 tests/javascript/old/milestones-non-auth.js delete mode 100644 tests/javascript/old/new-issue-non-auth.js delete mode 100644 tests/javascript/old/reporting-auth.js delete mode 100644 tests/javascript/old/reporting-non-auth.js delete mode 100644 tests/javascript/old/search-auth.js delete mode 100644 tests/javascript/old/search-non-auth.js delete mode 100644 tests/javascript/old/user-activity-auth.js delete mode 100644 tests/javascript/old/user-activity-non-auth.js rename tests/{python => unit}/__init__.py (100%) rename tests/{python => unit}/test_api_urls.py (100%) rename tests/{python => unit}/test_dashboard.py (100%) rename tests/{python => unit}/test_form.py (100%) rename tests/{python => unit}/test_helpers.py (100%) rename tests/{python => unit}/test_http_caching.py (100%) rename tests/{python => unit}/test_rendering.py (100%) rename tests/{python => unit}/test_topsites.py (100%) rename tests/{python => unit}/test_uploads.py (100%) rename tests/{python => unit}/test_urls.py (100%) rename tests/{python => unit}/test_webhook.py (100%) diff --git a/package.json b/package.json index f675d5021..fe8a3bae9 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,4 @@ - { +{ "title": "webcompat.com", "name": "webcompat", "description": "The webcompat.com is a tool to gather web compatibility bugs, inform the community and help to fix the web.", @@ -14,6 +14,7 @@ "node": ">= 4.x" }, "dependencies": { + "amd-to-commonjs-codemod": "^1.2.0", "cssrecipes-custom-media-queries": "0.3.0", "cssrecipes-defaults": "^0.5.0", "cssrecipes-grid": "^1.0.0", @@ -70,7 +71,7 @@ "project-update": "pip install --upgrade pip && npm update", "precommit": "lint-staged", "test": "npm run test:js && npm run test:python", - "test:js": "node_modules/.bin/intern-runner config=tests/intern", + "test:js": "node ./tests/functional/_intern.js", "test:python": "nosetests" }, "lint-staged": { diff --git a/tests/.eslintrc b/tests/.eslintrc index 95884cb22..83fec3ecd 100644 --- a/tests/.eslintrc +++ b/tests/.eslintrc @@ -1,5 +1,9 @@ { "globals": { - "intern": true + "intern": true, + "process": true + }, + "rules": { + "no-console": "off" } } diff --git a/tests/functional/_intern.js b/tests/functional/_intern.js new file mode 100644 index 000000000..a304ff912 --- /dev/null +++ b/tests/functional/_intern.js @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const intern = require("intern").default; + +const args = {}; +process.argv.forEach((val, index) => { + if (val.indexOf("=") !== -1) { + args[val.split("=")[0]] = val.split("=")[1]; + } else { + args[index] = val; + } +}); + +const siteRoot = args.siteRoot ? args.siteRoot : "http://localhost:5000"; + +let environments = []; +const browsers = args.browsers + ? args.browsers.replace(/\s/g, "").split(",") + : ["firefox", "chrome"]; + +browsers.forEach(function(b) { + environments.push({ + browserName: b.toLowerCase(), + marionette: true + }); +}); + +intern.configure({ + // Configuration object for webcompat + wc: { + pageLoadTimeout: args.wcPageLoadTimeout + ? parseInt(args.wcPageLoadTimeout, 10) + : 10000 + }, + + plugins: "./tests/functional/lib/setup.js", + + maxConcurrency: 1, + + // The port on which the instrumenting proxy will listen + proxyPort: 9090, + + // A fully qualified URL to the Intern proxy + proxyUrl: "http://127.0.0.1:9090/", + siteRoot: siteRoot, + tunnel: "selenium", + tunnelOptions: { + // this tells SeleniumTunnel to download geckodriver and chromedriver + drivers: ["firefox", "chrome"] + }, + + environments: environments, + + filterErrorStack: true, + reporters: ["pretty"], + + functionalSuites: ["./tests/functional/*.js"] +}); + +intern.run().catch(e => { + // This might not throw, BUG filed: https://github.com/theintern/intern/issues/868 + console.log(e); + process.exit(1); +}); diff --git a/tests/functional/comments-auth.js b/tests/functional/comments-auth.js new file mode 100755 index 000000000..896409008 --- /dev/null +++ b/tests/functional/comments-auth.js @@ -0,0 +1,147 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Comments (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "Comments form visible when logged in"() { + return ( + FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") + // Comment form visible for logged in users. + .findDisplayedByCssSelector(".js-Comment-form") + .end() + ); + }, + + "Posting a comment"() { + var originalCommentsLength; + var allCommentsLength; + return ( + FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") + .findAllByCssSelector(".js-Issue-comment") + .then(function(elms) { + originalCommentsLength = elms.length; + }) + .end() + .findByCssSelector("textarea.js-Comment-text") + .type("Today's date is " + new Date().toDateString()) + .end() + // click the comment button + .findByCssSelector(".js-Issue-comment-button") + .click() + .end() + .sleep(1000) + .findAllByCssSelector(".js-Issue-comment") + .then(function(elms) { + allCommentsLength = elms.length; + assert( + originalCommentsLength < allCommentsLength, + "Comment was successfully left." + ); + }) + ); + }, + + "Posting an empty comment fails"() { + var originalCommentsLength; + var allCommentsLength; + return ( + FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") + .findAllByCssSelector(".js-Issue-comment") + .then(function(elms) { + originalCommentsLength = elms.length; + }) + .end() + // click the comment button + .findByCssSelector(".js-Issue-comment-button") + .click() + .end() + .sleep(2000) + .findAllByCssSelector(".js-Issue-comment") + .then(function(elms) { + allCommentsLength = elms.length; + assert( + originalCommentsLength === allCommentsLength, + "Comment was not successfully left." + ); + }) + ); + }, + + "Add a screenshot to a comment"() { + return FunctionalHelpers.openPage( + this, + url("/issues/100"), + ".wc-Comment-body" + ) + .findById("image") + .type("tests/fixtures/green_square.png") + .end() + .sleep(2000) + .findByCssSelector(".js-Comment-text") + .getProperty("value") + .then(function(val) { + assert.include( + val, + "[![Screenshot Description](http://localhost:5000/uploads/", + "The image was correctly uploaded and its URL was copied to the comment text." + ); + }) + .end(); + }, + + "Pressing 'g' inside of comment textarea *doesn't* go to github issue"() { + return FunctionalHelpers.openPage( + this, + url("/issues/100"), + ".wc-Comment-submit" + ) + .findByCssSelector(".wc-Comment-submit") + .click() + .type("g") + .end() + .setFindTimeout(2000) + .findByCssSelector(".repo-container .issues-listing") + .then(assert.fail, function(err) { + assert.isTrue(/NoSuchElement/.test(String(err))); + }) + .end(); + }, + + "Pressing 'l' inside of comment textarea *doesn't* open the label editor box"() { + return FunctionalHelpers.openPage( + this, + url("/issues/100"), + ".wc-Comment-submit" + ) + .findByCssSelector(".wc-Comment-submit") + .click() + .type("l") + .end() + .setFindTimeout(2000) + .findByCssSelector(".js-LabelEditorLauncher") + .getAttribute("class") + .then(function(className) { + assert.notInclude(className, "is-active"); + }) + .end(); + } + } +}); diff --git a/tests/functional/comments-non-auth.js b/tests/functional/comments-non-auth.js new file mode 100755 index 000000000..839332ee2 --- /dev/null +++ b/tests/functional/comments-non-auth.js @@ -0,0 +1,25 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Comments (non-auth)", { + tests: { + "Comment form not visible for logged out users"() { + return FunctionalHelpers.openPage(this, url("/issues/200"), ".js-Issue") + .findByCssSelector(".js-Comment-form") + .then(assert.fail, function(err) { + assert.isTrue(/NoSuchElement/.test(String(err))); + }) + .end(); + } + } +}); diff --git a/tests/functional/contributors-non-auth.js b/tests/functional/contributors-non-auth.js new file mode 100755 index 000000000..08fa56e21 --- /dev/null +++ b/tests/functional/contributors-non-auth.js @@ -0,0 +1,109 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Contributors", { + tests: { + "page loads"() { + return FunctionalHelpers.openPage( + this, + url("/contributors"), + ".wc-Hero--contributors" + ) + .findByCssSelector(".js-Hero-title") + .getVisibleText() + .then(function(text) { + assert.include(text, "Welcome aboard!"); + }) + .end(); + }, + + "clicking first section closes it"() { + return FunctionalHelpers.openPage( + this, + url("/contributors"), + ".wc-Hero--contributors" + ) + .findByCssSelector(".contributors__item__title") + .click() + .end() + .findByCssSelector(".contributors__item__content") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-open", className); + }) + .end() + .findByCssSelector(".js-Hero-svg") + .getAttribute("class") + .then(function(className) { + assert.notEqual("is-active", className); + }) + .end(); + }, + + "clicking section toggles it"() { + return FunctionalHelpers.openPage( + this, + url("/contributors"), + ".wc-Hero--contributors" + ) + .findByCssSelector(".contributors__item__content.is-open") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true); + }) + .end() + .findByCssSelector(".js-Hero-svg.is-active") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true); + }) + .end() + .findByCssSelector(".contributors__item__title") + .click() + .end() + .findByCssSelector(".contributors__item__content") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-open", className); + }) + .end() + .findByCssSelector(".js-Hero-svg") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }); + }, + + "toggling section toggles lightbulb"() { + return FunctionalHelpers.openPage( + this, + url("/contributors"), + ".wc-Hero--contributors" + ) + .findByCssSelector(".js-Hero-svg.is-active") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true); + }) + .end() + .findByCssSelector(".contributors__item__title") + .click() + .end() + .findByCssSelector(".js-Hero-svg") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }); + } + } +}); diff --git a/tests/functional/history-navigation-non-auth.js b/tests/functional/history-navigation-non-auth.js new file mode 100755 index 000000000..10ad45917 --- /dev/null +++ b/tests/functional/history-navigation-non-auth.js @@ -0,0 +1,41 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("History navigation", { + tests: { + "Back button works from issues page"() { + return ( + FunctionalHelpers.openPage(this, url("/"), ".js-issues-link") + .findByCssSelector(".js-issues-link") + .click() + .end() + // check that the page is loaded + .findDisplayedByCssSelector(".wc-IssueList:nth-child(11)") + .end() + .getCurrentUrl() + .then(function(url) { + assert.include(url, "/issues"); + }) + .goBack() + // now check that we're back at the home page. + .findDisplayedByCssSelector(".wc-IssueList:nth-child(1)") + .end() + .getCurrentUrl() + .then(function(url) { + assert.notInclude(url, "/issues"); + }) + .end() + ); + } + } +}); diff --git a/tests/functional/image-uploads-non-auth.js b/tests/functional/image-uploads-non-auth.js new file mode 100755 index 000000000..051b39617 --- /dev/null +++ b/tests/functional/image-uploads-non-auth.js @@ -0,0 +1,203 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/*global WindowHelpers:true*/ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = intern.config.siteRoot + "/?open=1"; + +registerSuite("Image Uploads (non-auth)", { + tests: { + "postMessaged dataURI preview"() { + return ( + FunctionalHelpers.openPage(this, url, ".js-image-upload-label") + // send a small base64 encoded green test square + .execute( + 'postMessage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAIAAABLixI0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gYSAig452t/EQAAAClJREFUOMvtzkENAAAMg0A25ZU+E032AQEXoNcApCGFLX5paWlpaWl9dqq9AS6CKROfAAAAAElFTkSuQmCC", "http://localhost:5000")' + ) + .sleep(1000) + .findByCssSelector(".js-image-upload-label") + .getAttribute("style") + .then(function(inlineStyle) { + assert.include( + inlineStyle, + "data:image/png;base64,iVBOR", + "Base64 data shown as preview background" + ); + }) + .end() + ); + }, + + "postMessaged blob preview"() { + return ( + FunctionalHelpers.openPage(this, url, ".js-image-upload-label") + // Build up a green test square in canvas, toBlob that, and then postMessage the blob + // see window-helpers.js for more details. + .execute(function() { + WindowHelpers.getBlob().then(WindowHelpers.sendBlob); + }) + .sleep(1000) + .findByCssSelector(".js-image-upload-label") + .getAttribute("style") + .then(function(inlineStyle) { + assert.include( + inlineStyle, + "data:image/png;base64,iVBOR", + "Base64 data shown as preview background" + ); + }) + .end() + ); + }, + + "uploaded image file preview"() { + return FunctionalHelpers.openPage(this, url, ".js-image-upload-label") + .findById("image") + .type("tests/fixtures/green_square.png") + .sleep(1000) + .end() + .findByCssSelector(".js-image-upload-label") + .getAttribute("style") + .then(function(inlineStyle) { + assert.include( + inlineStyle, + "data:image/png;base64,iVBOR", + "Base64 data shown as preview background" + ); + }) + .end(); + }, + + "postMessaged dataURI image doesn't upload before form submission"() { + return ( + FunctionalHelpers.openPage(this, url, ".js-image-upload-label") + // send a small base64 encoded green test square + .execute( + 'postMessage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAIAAABLixI0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gYSAig452t/EQAAAClJREFUOMvtzkENAAAMg0A25ZU+E032AQEXoNcApCGFLX5paWlpaWl9dqq9AS6CKROfAAAAAElFTkSuQmCC", "http://localhost:5000")' + ) + .sleep(1000) + .findByCssSelector("#steps_reproduce") + .getProperty("value") + .then(function(val) { + assert.notInclude( + val, + "[![Screenshot Description](http://localhost:5000/uploads/", + "The data URI was not uploaded before form submission." + ); + }) + .end() + ); + }, + + "postMessaged blob image doesn't upload before form submission"() { + return ( + FunctionalHelpers.openPage(this, url, ".js-image-upload-label") + // Build up a green test square in canvas, toBlob that, and then postMessage the blob + .execute(function() { + WindowHelpers.getBlob().then(WindowHelpers.sendBlob); + }) + .sleep(1000) + .findByCssSelector("#steps_reproduce") + .getProperty("value") + .then(function(val) { + assert.notInclude( + val, + "[![Screenshot Description](http://localhost:5000/uploads/", + "The data URI was not uploaded before form submission." + ); + }) + .end() + ); + }, + + "uploaded image file doesn't upload before form submission"() { + return FunctionalHelpers.openPage(this, url, ".js-image-upload-label") + .findById("image") + .type("tests/fixtures/green_square.png") + .sleep(1000) + .end() + .findByCssSelector("#steps_reproduce") + .getProperty("value") + .then(function(val) { + assert.notInclude( + val, + "[![Screenshot Description](http://localhost:5000/uploads/", + "The data URI was not uploaded before form submission." + ); + }) + .end(); + }, + + "remove image upload button"() { + return ( + FunctionalHelpers.openPage(this, url, ".wc-UploadForm-button") + // send a small base64 encoded green test square + .execute( + 'postMessage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAIAAABLixI0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gYSAig452t/EQAAAClJREFUOMvtzkENAAAMg0A25ZU+E032AQEXoNcApCGFLX5paWlpaWl9dqq9AS6CKROfAAAAAElFTkSuQmCC", "http://localhost:5000")' + ) + .sleep(1000) + .findByCssSelector(".js-image-upload-label .wc-UploadForm-button") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "Remove button is displayed"); + }) + .end() + .findByCssSelector(".js-image-upload-label .wc-UploadForm-button") + .click() + .sleep(1000) + .end() + .findByCssSelector(".js-image-upload-label") + .getAttribute("style") + .then(function(inlineStyle) { + assert.notInclude( + inlineStyle, + "data:image/png;base64,iVBOR", + "Preview was removed" + ); + }) + .end() + .findByCssSelector("#steps_reproduce") + .getProperty("value") + .then(function(val) { + assert.notInclude( + val, + "[![Screenshot Description](http://localhost:5000/uploads/", + "The url to the image upload was correctly removed." + ); + }) + .end() + ); + }, + + "double image select works"() { + return FunctionalHelpers.openPage(this, url, ".wc-UploadForm-button") + .findById("image") + .type("tests/fixtures/green_square.png") + .sleep(1000) + .end() + .findByCssSelector(".js-image-upload-label .wc-UploadForm-button") + .click() + .sleep(1000) + .end() + .findById("image") + .type("tests/fixtures/green_square.png") + .end() + .sleep(1000) + .findByCssSelector(".js-image-upload-label") + .getAttribute("style") + .then(function(inlineStyle) { + assert.include( + inlineStyle, + "data:image/png;base64,iVBOR", + "Preview is shown" + ); + }) + .end(); + } + } +}); diff --git a/tests/functional/index-non-auth.js b/tests/functional/index-non-auth.js new file mode 100755 index 000000000..5a740ddf8 --- /dev/null +++ b/tests/functional/index-non-auth.js @@ -0,0 +1,119 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Index", { + tests: { + "front page loads"() { + return FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") + .findByCssSelector(".js-Hero-title") + .getVisibleText() + .then(function(text) { + assert.equal(text, "Bug reporting\nfor the internet."); + }) + .end(); + }, + + "reporter addon link is shown"() { + return FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") + .findByCssSelector(".js-Navbar-link") + .getVisibleText() + .then(function(text) { + assert.include(text, "Download our"); + }) + .end(); + }, + + "form toggles open then closed"() { + return ( + FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") + .findByCssSelector("#js-ReportBug") + .click() + .end() + .sleep(1000) + .findByCssSelector("#js-ReportForm") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "The form is displayed"); + }) + .end() + .findByCssSelector("#js-ReportBug") + .click() + .end() + // wait a bit for animation to finish + .sleep(1000) + .findByCssSelector("#js-ReportForm") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, false, "The form should be hidden"); + }) + ); + }, + + "browse issues (needstriage)"() { + return FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") + .findAllByCssSelector( + "#js-lastIssue .js-IssueList.wc-IssueList--needstriage" + ) + .then(function(elms) { + assert.equal(elms.length, 10, "10 issues should be displayed"); + }) + .end() + .findByCssSelector(".wc-IssueList--needstriage .wc-IssueList-count") + .getVisibleText() + .then(function(text) { + assert.match(text, /^Issue\s(\d+)$/, "Issue should have a number"); + }) + .end() + .findByCssSelector(".wc-IssueList--needstriage .wc-IssueList-header a") + .getAttribute("href") + .then(function(text) { + assert.match(text, /^\/issues\/\d+$/, "Link should have a number"); + }) + .end() + .findByCssSelector(".wc-IssueList--needstriage .wc-IssueList-header") + .getVisibleText() + .then(function(text) { + assert.match( + text, + /^Issue\s\d+:\s.+$/, + "Issue should have a non-empty title" + ); + }) + .end() + .findByCssSelector( + ".wc-IssueList--needstriage .wc-IssueList-metadata:nth-child(1)" + ) + .getVisibleText() + .then(function(text) { + assert.match( + text, + /^Opened:\s\d{4}\-\d{2}\-\d{2}/, + "Issue should display creation date" + ); + }) + .end() + .findByCssSelector( + ".wc-IssueList--needstriage .wc-IssueList-metadata:nth-child(2)" + ) + .getVisibleText() + .then(function(text) { + assert.match( + text, + /Comments:\s\d/, + "Issue should display number of comments" + ); + }) + .end(); + } + } +}); diff --git a/tests/functional/issue-list-non-auth.js b/tests/functional/issue-list-non-auth.js new file mode 100755 index 000000000..d35b6b81a --- /dev/null +++ b/tests/functional/issue-list-non-auth.js @@ -0,0 +1,447 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path, params) { + var base = intern.config.siteRoot + path; + return params ? base + params : base; +}; + +registerSuite("Issue-list", { + tests: { + "FilterView renders"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-SearchIssue-filter" + ) + .findAllByCssSelector("button.js-Tag") + .then(function(elms) { + assert.equal(elms.length, 6, "All filter buttons are displayed"); + }) + .end(); + }, + + "IssueListView renders"() { + return FunctionalHelpers.openPage(this, url("/issues"), ".js-IssueList") + .findByCssSelector(".js-IssueList") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "IssueList container is visible."); + }) + .sleep(1000) + .end() + .findByCssSelector(".js-list-issue .js-IssueList") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "IssueList item is visible."); + }) + .end() + .findByCssSelector(".js-IssueList .wc-IssueList-header") + .getVisibleText() + .then(function(text) { + assert.match( + text, + /^Issue\s\d+:\s.+$/, + "Issue should have a non-empty title" + ); + }) + .end() + .findByCssSelector( + ".js-IssueList:nth-child(1) > div:nth-child(1) > p:nth-child(2)" + ) + .getVisibleText() + .then(function(text) { + assert.match( + text, + /comments:\s\d+$/i, + "Issue should display number of comments" + ); + assert.match( + text, + /^Opened:\s\d{4}\-\d{2}\-\d{2}.+/, + "Issue should display creation date" + ); + }) + .end(); + }, + + "PaginationControlsView tests"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-Pagination-controls" + ) + .findByCssSelector(".js-Pagination-controls") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "IssueList container is visible."); + }) + .end() + .findByCssSelector(".js-Pagination-previous.is-disabled") + .getAttribute("class") + .then(function(className) { + assert.include( + className, + "is-disabled", + "First page load should have disabled prev button" + ); + }) + .end() + .findByCssSelector(".js-Pagination-next") + .click() + .end() + .findByCssSelector(".js-Pagination-previous:not(.is-disabled)") + .getAttribute("class") + .then(function(className) { + assert.notInclude( + className, + "is-disabled", + "Clicking next enables prev button" + ); + }) + .end() + .findByCssSelector(".js-Pagination-previous") + .click() + .end() + .findByCssSelector(".js-Pagination-previous.is-disabled") + .getAttribute("class") + .then(function(className) { + assert.include( + className, + "is-disabled", + "Going back from first next click should have disabled prev button" + ); + }) + .end(); + }, + + "Pagination dropdown tests"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-Pagination-controls" + ) + .findByCssSelector(".js-Dropdown-pagination") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal( + isDisplayed, + true, + "pagination dropdown container is visible." + ); + }) + .end() + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle") + .click() + .end() + .findByCssSelector(".js-Dropdown-pagination") + .getAttribute("class") + .then(function(className) { + assert.include( + className, + "is-active", + "clicking dropdown adds is-active class" + ); + }) + .end() + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-options") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "dropdown options are visible."); + }) + .end() + .findByCssSelector( + ".js-Dropdown-pagination .js-Dropdown-item:nth-child(3) > .js-Dropdown-link:nth-child(1)" + ) + .click() + .end() + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-label") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "Show 100", + "Clicking first option updated dropdown label" + ); + }) + .end() + .findDisplayedByCssSelector(".js-IssueList:nth-child(51)") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "More than 50 issues were loaded."); + }) + .end(); + }, + + "Pressing g goes to github issues"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-Pagination-controls" + ) + .findByCssSelector("body") + .click() + .type("g") + .end() + .sleep(500) + .getCurrentUrl() + .then(function(url) { + assert.match( + url, + /[https://github.com/^*/^*/issues/]/, + "We're at GitHub now." + ); + }) + .end(); + }, + + "Pressing g inside of search input *doesn't* go to github issues"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + "#js-SearchForm-input" + ) + .findByCssSelector("#js-SearchForm-input") + .click() + .type("g") + .end() + .setFindTimeout(0) + .findByCssSelector(".repo-container .issues-listing") + .then(assert.fail, function(err) { + assert.isTrue(/NoSuchElement/.test(String(err))); + }) + .end(); + }, + + "Loading issues page has default params in URL"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-IssueList:nth-of-type(1)" + ) + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "page=1&per_page=50&state=open", + "Default model params are added to the URL" + ); + }); + }, + + "Loading partial params results in merge with defaults"() { + var params = "?page=2"; + return FunctionalHelpers.openPage( + this, + url("/issues", params), + ".js-IssueList:nth-of-type(1)" + ) + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "page=2&per_page=50&state=open", + "Default model params are merged with partial URL params" + ); + }); + }, + + "Dropdowns reflect state from URL"() { + var params = "?per_page=25&sort=updated&direction=desc&state=all"; + + return FunctionalHelpers.openPage( + this, + url("/issues", params), + ".js-IssueList:nth-of-type(1)" + ) + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle h1") + .getVisibleText() + .then(function(text) { + assert.equal( + text, + "Show 25", + "Pagination dropdown label is updated from URL params" + ); + }) + .end() + .findAllByCssSelector(".js-Dropdown-sort .js-Dropdown-toggle h1") + .getVisibleText() + .then(function(text) { + assert.equal( + text, + "Recently Updated", + "Sort dropdown label is updated from URL params" + ); + }) + .end(); + }, + + "Going back in history updates issue list and URL state"() { + var params = "?per_page=25"; + + return ( + FunctionalHelpers.openPage( + this, + url("/issues", params), + ".js-IssueList:nth-of-type(1)" + ) + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle h1") + .getVisibleText() + .then(function(text) { + assert.equal( + text, + "Show 25", + "Pagination dropdown label is updated from URL params" + ); + }) + .end() + // Select "Show 100" from pagination dropdown + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle") + .click() + .end() + .findByCssSelector( + ".js-Dropdown-pagination li.js-Dropdown-item:nth-child(3) > a:nth-child(1)" + ) + .click() + .end() + // find something so we know issues have been loaded + .findByCssSelector(".js-IssueList:nth-of-type(1)") + .execute(function() { + history.back(); + }) + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "per_page=25", + "URL param is back to where we started" + ); + }) + .end() + .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle h1") + .getVisibleText() + .then(function(text) { + assert.equal( + text, + "Show 25", + "Pagination dropdown label is back to where we started" + ); + }) + .end() + ); + }, + + "Loading URL with stage param loads issues"() { + var params = + "?page=1&per_page=50&state=open&stage=needstriage&sort=created&direction=desc"; + + return FunctionalHelpers.openPage( + this, + url("/issues", params), + ".js-IssueList:nth-of-type(1)" + ) + .findByCssSelector(".js-Tag.is-active") + .getVisibleText() + .then(function(text) { + assert.equal( + "Needs Triage", + text, + "Needs Triage filter is selected." + ); + }) + .end(); + }, + + "Clicking on a stage filter adds the correct param to the URL"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-IssueList:nth-of-type(1)" + ) + .findByCssSelector('[data-filter="contactready"]') + .click() + .end() + // find something so we know the page has loaded + .findByCssSelector(".wc-IssueList:nth-of-type(1)") + .end() + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "stage=contactready", + "Stage filter added to URL correctly." + ); + }) + .end() + ); + }, + + "Toggling a stage filter doesn't leave the param in the URL"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-IssueList:nth-of-type(1)" + ) + .findByCssSelector('[data-filter="closed"]') + .click() + .end() + // find something so we know the page has loaded + .findByCssSelector(".wc-IssueList:nth-of-type(1)") + .end() + .findByCssSelector('[data-filter="closed"]') + .click() + .end() + .getCurrentUrl() + .then(function(currUrl) { + assert.notInclude( + currUrl, + "stage=closed", + "Stage filter added then removed from URL." + ); + }) + .end() + ); + }, + + "Toggling between stage filters results in last param in URL"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-IssueList:nth-of-type(1)" + ) + .findByCssSelector('[data-filter="closed"]') + .click() + .end() + // find something so we know the page has loaded + .findByCssSelector(".wc-IssueList:nth-of-type(1)") + .end() + .findByCssSelector('[data-filter="sitewait"]') + .click() + .end() + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "stage=sitewait", + "Stage filter added to URL correctly." + ); + assert.notInclude( + currUrl, + "stage=closed", + "Stage removed from URL correctly." + ); + }) + .end() + ); + } + } +}); diff --git a/tests/functional/issues-auth.js b/tests/functional/issues-auth.js new file mode 100755 index 000000000..a1b90bf1f --- /dev/null +++ b/tests/functional/issues-auth.js @@ -0,0 +1,48 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Issues (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "Pressing 'l' opens the label editor box"() { + return FunctionalHelpers.openPage( + this, + url("/issues/70"), + ".wc-Issue-commentSubmit" + ) + .findByCssSelector("body") + .click() + .type("l") + .end() + .findByCssSelector(".js-LabelEditorLauncher") + .then(function(element) { + element + .getAttribute("class") + .then(function(classList) { + assert.include(classList, "is-active"); + }) + .catch(function(error) { + console.log(error); + }); + }) + .end(); + } + } +}); diff --git a/tests/functional/issues-non-auth.js b/tests/functional/issues-non-auth.js new file mode 100755 index 000000000..4f0d7aaf9 --- /dev/null +++ b/tests/functional/issues-non-auth.js @@ -0,0 +1,119 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Issues", { + tests: { + "Issue page loads"() { + return FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") + .findDisplayedByCssSelector(".wc-Issue-information-header") + .getVisibleText() + .then(function(text) { + assert.include(text, "#100", "Issue title displayed"); + }) + .end() + .findByCssSelector(".js-Issue-reporter") + .getVisibleText() + .then(function(text) { + assert.equal(text, "miketaylr", "Issue reporter displayed."); + }) + .end() + .findByCssSelector(".js-Label") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true); + }); + }, + + "Issue comments load"() { + return FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") + .findDisplayedByCssSelector(".js-Issue-comment") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true); + }) + .findByCssSelector(".js-Comment-owner") + .getVisibleText() + .then(function(text) { + assert.equal(text, "GIGANTOR", "Commenter name displayed."); + }) + .end() + .findByCssSelector(".js-Comment-content") + .getVisibleText() + .then(function(text) { + assert.equal( + text, + "Today's date is Mon Sep 28 2015", + "Comment is displayed." + ); + }); + }, + + "Pressing g goes to the github issue page"() { + return FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") + .findByCssSelector("body") + .click() + .type("g") + .end() + .sleep(500) + .getCurrentUrl() + .then(function(url) { + assert.match( + url, + /[https://github.com/^*/^*/issues/100]/, + "We're at the GitHub issue page now." + ); + }); + }, + + "NSFW images are blurred"() { + return FunctionalHelpers.openPage(this, url("/issues/396"), ".js-Issue") + .findDisplayedByCssSelector( + ".js-Issue-commentList .js-Comment-content p" + ) + .getAttribute("class") + .then(function(className) { + assert.include(className, "wc-Comment-content-nsfw"); + }) + .end(); + }, + + "Clicking NSFW images toggles between blurry and not-blurry"() { + return FunctionalHelpers.openPage(this, url("/issues/396"), ".js-Issue") + .findDisplayedByCssSelector( + ".js-Issue-commentList .js-Comment-content p" + ) + .getAttribute("class") + .then(function(className) { + assert.include(className, "wc-Comment-content-nsfw"); + assert.notInclude(className, "wc-Comment-content-nsfw--display"); + }) + .click() + .end() + .findByCssSelector(".js-Issue-commentList .js-Comment-content p") + .getAttribute("class") + .then(function(className) { + assert.include(className, "wc-Comment-content-nsfw"); + assert.include(className, "wc-Comment-content-nsfw--display"); + }) + .click() + .end() + .findByCssSelector(".js-Issue-commentList .js-Comment-content p") + .getAttribute("class") + .then(function(className) { + assert.include(className, "wc-Comment-content-nsfw"); + assert.notInclude(className, "wc-Comment-content-nsfw--display"); + }) + .end(); + } + } +}); diff --git a/tests/functional/labels-auth.js b/tests/functional/labels-auth.js new file mode 100755 index 000000000..14296058f --- /dev/null +++ b/tests/functional/labels-auth.js @@ -0,0 +1,111 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Labels (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "Label editor opens then closes (clicks)": function() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-LabelEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector(".js-LabelEditorLauncher") + .click() + .end() + .findByCssSelector(".js-CategoryEditor") + .end() + .findByCssSelector(".js-LabelEditorLauncher") + .click() + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + }, + + "Label editor opens then closes (key events)": function() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-LabelEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector("body") + .type("l") + .end() + .findByCssSelector(".wc-CategoryEditor-search") + .pressKeys("\uE00C") + .end() + .findByCssSelector(".js-LabelEditorLauncher") + .click() + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + }, + + "Clicking outside label editor closes it": function() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-LabelEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector(".js-LabelEditorLauncher") + .click() + .end() + .findByCssSelector(".js-CategoryEditor") + .end() + .findByCssSelector("main") + .click() + .end() + .findByCssSelector(".js-LabelEditorLauncher") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + }, + + "Clicking close button actually closes it?": function() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-LabelEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector(".js-LabelEditorLauncher") + .click() + .end() + .findByCssSelector(".js-CategoryEditor-close") + .click() + .end() + .findByCssSelector(".js-LabelEditorLauncher") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + } + } +}); diff --git a/tests/functional/lib/helpers.js b/tests/functional/lib/helpers.js new file mode 100644 index 000000000..a9d9140f8 --- /dev/null +++ b/tests/functional/lib/helpers.js @@ -0,0 +1,55 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/*eslint no-console: ["error", { allow: ["log", "error"] }] */ +const intern = require("intern").default; +var config = intern.config; + +var url = function(path, params) { + var base = intern.config.siteRoot + path; + return params ? base + params : base; +}; + +/* +Use this method to make sure a page is loaded before trying to find +things inside of it. The optional boolean longer arg at the end can +be used for tests that need more time. +*/ +function openPage(context, path, readySelector, longerTimeout) { + var timeout = longerTimeout ? 20000 : config.wc.pageLoadTimeout; + + return ( + context.remote + .get(path) + .setFindTimeout(timeout) + // Wait until the `readySelector` element is found to return. + .findByCssSelector(readySelector) + .end() + .then(null, function(err) { + return context.remote + .getCurrentUrl() + .then(function(resultUrl) { + console.log("Error fetching %s", resultUrl); + }) + .end() + .then(function() { + throw err; + }); + }) + ); +} + +function login(context) { + return openPage(context, url("/login"), "body").end(); +} + +function logout(context) { + return openPage(context, url("/logout"), "body").clearCookies().end(); +} + +module.exports = { + openPage: openPage, + login: login, + logout: logout +}; diff --git a/tests/functional/lib/setup.js b/tests/functional/lib/setup.js new file mode 100644 index 000000000..0d4b2460e --- /dev/null +++ b/tests/functional/lib/setup.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const intern = require("intern").default; +const http = require("http"); + +var url = function(path, params) { + var base = intern.config.siteRoot + path; + return params ? base + params : base; +}; + +/* +This method makes a call to our API and +checks that the server is returning fixture data, +it will also check if there's anything wrong with the server. +*/ + +intern.registerPlugin("checkServer", function() { + return new Promise(function(resolve, reject) { + var request = http.get(url("/api/issues/100"), function(response) { + response.on("data", function(data) { + var json = JSON.parse(data); + if (!json.hasOwnProperty("_fixture")) { + reject( + new Error( + ` + ======================================================= + It seems like you didn't start the server in test mode. + Open another terminal and window type: + \x1b[32m npm run start:test\x1b[0m + or + \x1b[32m python run.py -t\x1b[0m + ======================================================= + ` + ) + ); + } else { + resolve("All is well!"); + } + }); + }); + + // Handle connection errors. + request.on("error", function() { + reject( + new Error( + ` + ====================================================== + Oops, something went wrong. Try restarting the server. + Open another terminal and window type: + \x1b[32m npm run start:test\x1b[0m + or + \x1b[32m python run.py -t\x1b[0m + ====================================================== + ` + ) + ); + }); + request.end(); + }); +}); diff --git a/tests/javascript/old/lib/window-helpers.js b/tests/functional/lib/window-helpers.js similarity index 100% rename from tests/javascript/old/lib/window-helpers.js rename to tests/functional/lib/window-helpers.js diff --git a/tests/functional/milestones-auth.js b/tests/functional/milestones-auth.js new file mode 100755 index 000000000..f887b67d4 --- /dev/null +++ b/tests/functional/milestones-auth.js @@ -0,0 +1,111 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Milestones (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "Milestone editor opens then closes (clicks)"() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-MilestoneEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector(".js-MilestoneEditorLauncher") + .click() + .end() + .findByCssSelector(".js-CategoryEditor") + .end() + .findByCssSelector(".js-MilestoneEditorLauncher") + .click() + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + }, + + "Milestone editor opens then closes (key events)"() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-MilestoneEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector("body") + .type("m") + .end() + .findByCssSelector(".wc-CategoryEditor-search") + .type("\uE00C") + .end() + .findByCssSelector(".js-MilestoneEditorLauncher") + .click() + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + }, + + "Clicking outside milestone editor closes it"() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-MilestoneEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector(".js-MilestoneEditorLauncher") + .click() + .end() + .findByCssSelector(".js-CategoryEditor") + .end() + .findByCssSelector("main") + .click() + .end() + .findByCssSelector(".js-MilestoneEditorLauncher") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + }, + + "Clicking close button actually closes it?"() { + return FunctionalHelpers.openPage( + this, + url("/issues/2"), + ".js-MilestoneEditorLauncher", + true /* longerTimeout */ + ) + .findByCssSelector(".js-MilestoneEditorLauncher") + .click() + .end() + .findByCssSelector(".js-CategoryEditor-close") + .click() + .end() + .findByCssSelector(".js-MilestoneEditorLauncher") + .getAttribute("class") + .then(function(className) { + assert.notInclude("is-active", className); + }) + .end(); + } + } +}); diff --git a/tests/functional/milestones-non-auth.js b/tests/functional/milestones-non-auth.js new file mode 100755 index 000000000..493141fed --- /dev/null +++ b/tests/functional/milestones-non-auth.js @@ -0,0 +1,48 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Milestones (non-auth)", { + tests: { + "Page loads without milestone set": function() { + return FunctionalHelpers.openPage( + this, + url("/issues/9"), + ".js-Issue", + true /* longerTimeout */ + ) + .findByCssSelector(".js-Issue-title") + .getVisibleText() + .then(function(text) { + // check that the title loaded, it won't be there if the page didn't render. + assert.include(text, "No Milestone."); + }) + .end(); + }, + + "Missing status error displays": function() { + return FunctionalHelpers.openPage( + this, + url("/issues/9"), + ".js-Issue", + true /* longerTimeout */ + ) + .findByCssSelector(".js-Milestone") + .getVisibleText() + .then(function(text) { + // check that the title loaded, it won't be there if the page didn't render. + assert.equal(text, "Error: no status for this issue"); + }) + .end(); + } + } +}); diff --git a/tests/functional/new-issue-non-auth.js b/tests/functional/new-issue-non-auth.js new file mode 100755 index 000000000..d65b45343 --- /dev/null +++ b/tests/functional/new-issue-non-auth.js @@ -0,0 +1,31 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("New Issue Page", { + tests: { + "new issue page loads"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".js-Navbar-link" + ) + .findByCssSelector(".js-Navbar-link") + .getVisibleText() + .then(function(text) { + assert.equal(text, "Home"); + assert.notInclude(text, "Download our"); + }) + .end(); + } + } +}); diff --git a/tests/functional/reporting-auth.js b/tests/functional/reporting-auth.js new file mode 100755 index 000000000..4028da577 --- /dev/null +++ b/tests/functional/reporting-auth.js @@ -0,0 +1,38 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Reporting (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "Report button shows name"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".js-Navbar-link" + ) + .findByCssSelector("#submitgithub") + .getVisibleText() + .then(function(text) { + assert.include(text, "Report as"); //Report as FooUser (logged in) + }) + .end(); + } + } +}); diff --git a/tests/functional/reporting-non-auth.js b/tests/functional/reporting-non-auth.js new file mode 100755 index 000000000..ce84558be --- /dev/null +++ b/tests/functional/reporting-non-auth.js @@ -0,0 +1,305 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); +const path = require("path"); + +var cwd = intern.config.basePath; +var VALID_IMAGE_PATH = path.join(cwd, "tests/fixtures", "green_square.png"); +var BAD_IMAGE_PATH = path.join(cwd, "tests/fixtures", "evil.py"); +var DETAILS_STRING = + "Encountered error: NS_ERROR_DOM_MEDIA_DEMUXER_ERR (0x806e000c)%0ALocation: virtual%0ARefPtrMP4Demuxer::InitPromise mozilla::MP4Demuxer::Init()%0AError information:%0AIncomplete MP4 metadata%0AMedia URL: file:///Users/potch/Documents/mozilla/media.mp4"; +var DETAILS_STRING2 = "Encountered+error:+NS_ERROR_DOM_MEDIA_DEMUXER_ERR"; + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("Reporting (non-auth)", { + tests: { + "Submit buttons are disabled"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + .findAllByCssSelector(".wc-ReportForm-actions-button button") + .getAttribute("class") + .then(function(classNames) { + classNames.forEach(function(className) { + assert.include(className, "is-disabled"); + }); + }) + .end(); + }, + + "Wyciwyg bug workaround"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new?url=wyciwyg://0/http://bbs.csdn.net/topics/20282413"), + "#url" + ) + .findByCssSelector("#url") + .getProperty("value") + .then(function(value) { + assert.notInclude(value, "wyciwyg://0/"); + }) + .end(); + }, + + "Report button shows via GitHub"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + .findByCssSelector("#submitgithub") + .getVisibleText() + .then(function(text) { + assert.include(text, "Report via"); //Report via GitHub (logged out) + }) + .end(); + }, + + "URL validation"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + .findByCssSelector("#url") + .click() + .end() + .execute(function() { + var elm = document.querySelector("#url"); + WindowHelpers.sendEvent(elm, "input"); + }) + .sleep(500) + .findByCssSelector(".wc-Form-helpMessage") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "A valid URL is required", + "URL validation message is shown" + ); + }) + .end() + .findByCssSelector("#url") + .type("sup") + .end() + .waitForDeletedByCssSelector(".wc-Form-helpMessage") + .end(); + }, + + "Description validation"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + .findByCssSelector("#description") + .click() + .end() + .execute(function() { + var elm = document.querySelector("#description"); + WindowHelpers.sendEvent(elm, "input"); + }) + .sleep(500) + .findByCssSelector(".wc-Form-helpMessage") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "Description required.", + "Description validation message is shown" + ); + }) + .end() + // enter a bug description + .findByCssSelector("#description") + .type("bug description") + .end() + // validation message should be gone + .waitForDeletedByCssSelector(".wc-Form-helpMessage") + .end() + ); + }, + + "(optional) browser + os validation"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + // make sure we can see the valid checkbox (i.e. it's background image is non-empty) + .execute(function() { + return window + .getComputedStyle( + document.querySelector(".js-bug-form-os"), + ":after" + ) + .getPropertyValue("background-image"); + }) + .then(function(bgImage) { + assert.include( + bgImage, + "valid.svg", + "The valid checkbox pseudo is visible" + ); + }) + .end() + .execute(function() { + var elm = document.querySelector("#os"); + elm.value = ""; + WindowHelpers.sendEvent(elm, "input"); + }) + .end() + .sleep(500) + // make sure we can't see the valid checkbox (i.e. it's background image is empty) + .execute(function() { + return window + .getComputedStyle( + document.querySelector(".js-bug-form-os"), + ":after" + ) + .getPropertyValue("background-image"); + }) + .then(function(bgImage) { + assert.notInclude( + bgImage, + "valid.svg", + "The valid checkbox pseudo is not visible" + ); + }) + .end() + ); + }, + + "Image extension validation"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + .findByCssSelector("#image") + .type(BAD_IMAGE_PATH) + .end() + .findByCssSelector(".wc-Form-helpMessage--imageUpload") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "Image must be one of the following", + "Image type validation message is shown" + ); + }) + .end() + // pick a valid file type + .findByCssSelector("#image") + .type(VALID_IMAGE_PATH) + .end() + // validation message should be gone + .waitForDeletedByCssSelector(".wc-Form-helpMessage--imageUpload") + .end() + ); + }, + + "Submits are enabled"() { + return ( + FunctionalHelpers.openPage( + this, + url("/issues/new"), + ".wc-ReportForm-actions-button" + ) + // pick a valid file type + .findByCssSelector("#image") + .type(VALID_IMAGE_PATH) + .end() + .findByCssSelector("#url") + .type("http://coolguy.biz") + .end() + // pick a problem type + .findByCssSelector("#problem_category-0") + .click() + .end() + .findByCssSelector("#description") + .type("test for desktop site") + //.click() + .end() + // wait a bit + .sleep(250) + // now make sure the buttons aren't disabled anymore + .findAllByCssSelector(".wc-ReportForm-actions-button button") + .getAttribute("class") + .then(function(classNames) { + classNames.forEach(function(className) { + assert.notInclude(className, "is-disabled"); + }); + }) + .end() + ); + }, + + "problem_type param selects problem type"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new?problem_type=video_bug"), + ".wc-ReportForm-actions-button" + ) + .findByCssSelector("[value=video_bug]") + .isSelected() + .then(function(isSelected) { + assert.isTrue(isSelected, "The right option is selected"); + }) + .end(); + }, + + "details param adds info to description"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new?details=" + DETAILS_STRING), + "#description" + ) + .findByCssSelector("#steps_reproduce") + .getProperty("value") + .then(function(text) { + assert.include( + text, + "Encountered error: NS_ERROR_DOM_MEDIA_DEMUXER_ERR (0x806e000c)\nLocation: virtual\nRefPtrMP4Demuxer::InitPromise mozilla::MP4Demuxer::Init()\nError information:\nIncomplete MP4 metadata\nMedia URL: file:///Users/potch/Documents/mozilla/media.mp4" + ); + }) + .end(); + }, + + "details param: + decoded as space"() { + return FunctionalHelpers.openPage( + this, + url("/issues/new?details=" + DETAILS_STRING2), + "#description" + ) + .findByCssSelector("#steps_reproduce") + .getProperty("value") + .then(function(text) { + assert.notInclude( + text, + "Encountered+error:+NS_ERROR_DOM_MEDIA_DEMUXER_ERR", + "+ not found in decoded string" + ); + assert.include( + text, + "Encountered error: NS_ERROR_DOM_MEDIA_DEMUXER_ERR", + "+ replaced with space" + ); + }) + .end(); + } + } +}); diff --git a/tests/functional/search-auth.js b/tests/functional/search-auth.js new file mode 100755 index 000000000..e2e11499e --- /dev/null +++ b/tests/functional/search-auth.js @@ -0,0 +1,222 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path, params) { + var fullUrl = params !== undefined + ? intern.config.siteRoot + path + params + : intern.config.siteRoot + path; + return fullUrl; +}; + +registerSuite("Search (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "Search/filter interaction"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".wc-SearchForm-item" + ) + .findDisplayedByCssSelector(".wc-SearchForm-item") + .click() + .type("taco") + .end() + .findAllByCssSelector("button.wc-Tag--needstriage") + .click() + .end() + .findByCssSelector(".wc-SearchForm-item") + .getVisibleText() + .then(function(text) { + assert.equal(text, "", "Clicking filter should empty search text"); + }) + .end() + .findAllByCssSelector("button.wc-Tag--needstriage") + .click() + .end() + .findByCssSelector(".wc-SearchForm-item") + .click() + .type("taco") + .end() + .findAllByCssSelector("button.wc-Tag--needstriage") + .getAttribute("class") + .then(function(className) { + assert.notInclude( + className, + "is-active", + "Searching should clear all filters" + ); + }) + .end(); + }, + + "Results are loaded from the query params"() { + var params = + "?page=1&per_page=50&state=open&stage=all&sort=created&direction=desc&q=vladvlad"; + return FunctionalHelpers.openPage( + this, + url("/issues", params), + ".wc-IssueList:nth-of-type(1)" + ) + .findDisplayedByCssSelector(".wc-IssueList:nth-of-type(1) .wc-Link") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "vladvlad", + "The search query results show up on the page." + ); + }) + .end() + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "q=vladvlad", + "Our params didn't go anywhere." + ); + }) + .end(); + }, + + "Search works by icon click"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".wc-IssueList:nth-of-type(10)" + ) + .findByCssSelector(".js-SearchForm input") + .type("vladvlad") + .end() + .findByCssSelector(".js-SearchForm button") + .click() + .end() + .findDisplayedByCssSelector(".wc-IssueList:only-of-type a") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "vladvlad", + "The search results show up on the page." + ); + }) + .end(); + }, + + "Search works by Return key"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + ".js-SearchForm input" + ) + .findDisplayedByCssSelector(".js-SearchForm input") + .type("vladvlad") + .type("\uE007") + .end() + .findDisplayedByCssSelector(".wc-IssueList:only-of-type a") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "vladvlad", + "The search results show up on the page." + ); + }) + .end(); + }, + + "Search from the homepage"() { + return ( + FunctionalHelpers.openPage(this, url("/"), ".js-SearchBarOpen") + .get(url("/")) + .findByCssSelector(".js-SearchBarOpen") + .click() + .end() + // Wait for animation to complete. + .sleep(1000) + .findByCssSelector(".js-SearchBar input") + .click() + .type("vladvlad") + .type("\uE007") + .end() + .findDisplayedByCssSelector(".wc-IssueList:only-of-type a") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "vladvlad", + "The search query results show up on the page." + ); + }) + .end() + .getCurrentUrl() + .then(function(currUrl) { + assert.include(currUrl, "page=1", "Default params got merged."); + }) + .end() + ); + }, + + "Search with a dash works"() { + // load up a garbage search, so we can more easily detect when + // the search values we want are loaded. + var searchParam = "?q=jfdkjfkdjfkdjfdkjfkd"; + return FunctionalHelpers.openPage( + this, + url("/issues", searchParam), + ".wc-SearchIssue-noResults-title" + ) + .findByCssSelector("#js-SearchForm-input") + .clearValue() + .click() + .type("label:status-tacos") + .type("\uE007") + .end() + .findDisplayedByCssSelector( + ".wc-IssueList:first-of-type .js-Issue-label" + ) + .getVisibleText() + .then(function(text) { + assert.include( + text, + "tacos", + "The label:status-tacos search worked." + ); + }) + .end(); + }, + + "Search input is loaded from q param (with dashes)"() { + // load up a garbage search, so we can more easily detect when + // the search values we want are loaded. + var searchParam = "?q=one:two-three"; + return FunctionalHelpers.openPage( + this, + url("/issues", searchParam), + ".wc-SearchIssue-noResults-title" + ) + .findByCssSelector("#js-SearchForm-input") + .getProperty("value") + .then(function(text) { + assert.include( + text, + "one:two-three", + "The q param populated the search input." + ); + }) + .end(); + } + } +}); diff --git a/tests/functional/search-non-auth.js b/tests/functional/search-non-auth.js new file mode 100755 index 000000000..a823bd309 --- /dev/null +++ b/tests/functional/search-non-auth.js @@ -0,0 +1,116 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path, params) { + var base = intern.config.siteRoot + path; + return params ? base + params : base; +}; + +registerSuite("Search (non-auth)", { + tests: { + "Pressing g inside of search input *doesnt* go to github issues"() { + return ( + FunctionalHelpers.openPage(this, url("/issues"), "#js-SearchForm-input") + .findByCssSelector("#js-SearchForm-input") + .click() + .type("g") + .end() + // set a short timeout, so we don't have to wait 10 seconds + // to realize we're not at GitHub. + .setFindTimeout(0) + .findByCssSelector(".repo-container .issues-listing") + .then(assert.fail, function(err) { + assert.isTrue(/NoSuchElement/.test(String(err))); + }) + .end() + ); + }, + + "Clicking on label search adds query parameter to the URL"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + "[data-remotename=browser-android" + ) + .findByCssSelector("[data-remotename=browser-android]") + .click() + .end() + .getCurrentUrl() + .then(function(currUrl) { + assert.include( + currUrl, + "q=label%3Abrowser-android", + "Url updated with label name" + ); + }) + .end(); + }, + + "Clicking on label search updates the search input"() { + return FunctionalHelpers.openPage( + this, + url("/issues"), + "[data-remotename=browser-android" + ) + .findByCssSelector("[data-remotename=browser-android]") + .click() + .end() + .findDisplayedById("js-SearchForm-input") + .getProperty("value") + .then(function(searchText) { + assert.include( + searchText, + "label:browser-android", + "Url updated with label name" + ); + }) + .end(); + }, + + "Search input is visible"() { + return FunctionalHelpers.openPage(this, url("/issues"), ".js-SearchForm") + .findByCssSelector(".js-SearchForm") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal( + isDisplayed, + true, + "Search input is visible for non-authed users." + ); + }) + .end(); + }, + + "Empty search input removes q param"() { + // load up a garbage search, so we can more easily detect when + // the search values we want are loaded. + var searchParam = "?q=fffffff"; + return FunctionalHelpers.openPage( + this, + url("/issues", searchParam), + ".js-SearchForm" + ) + .findByCssSelector("#js-SearchForm-input") + .clearValue() + .click() + .type("") + .type("\uE007") + .sleep(1000) + .getCurrentUrl() + .then(function(currUrl) { + assert.notInclude( + currUrl, + "q=fffffff", + "old search param was removed" + ); + }) + .end(); + } + } +}); diff --git a/tests/functional/user-activity-auth.js b/tests/functional/user-activity-auth.js new file mode 100755 index 000000000..c1f316fce --- /dev/null +++ b/tests/functional/user-activity-auth.js @@ -0,0 +1,105 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("User Activity (auth)", { + before() { + return FunctionalHelpers.login(this); + }, + + after() { + return FunctionalHelpers.logout(this); + }, + + tests: { + "We're at the right place"() { + var username; + return FunctionalHelpers.openPage(this, url("/me"), ".js-username") + .findByCssSelector(".wc-UIContent .wc-Title--l") + .getVisibleText() + .then(function(text) { + var usernameEnd = text.indexOf("'s activity"); + username = text.slice(0, usernameEnd); + }) + .getCurrentUrl() + .then(function(currURL) { + assert.include( + currURL, + username, + "The redirected URL has our username in it." + ); + }) + .end(); + }, + + "IssueListView renders"() { + return FunctionalHelpers.openPage(this, url("/me"), ".js-list-issue") + .findDisplayedByCssSelector(".js-list-issue") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "IssueList container is visible."); + }) + .end() + .findDisplayedByCssSelector(".js-list-issue .js-IssueList") + .isDisplayed() + .then(function(isDisplayed) { + assert.equal(isDisplayed, true, "IssueList item is visible."); + }) + .end() + .findByCssSelector(".js-IssueList .wc-IssueList-header") + .getVisibleText() + .then(function(text) { + assert.match( + text, + /^Issue\s\d+:\s.+$/, + "Issue should have a non-empty title" + ); + }) + .end() + .findByCssSelector( + ".js-IssueList:nth-child(1) > div:nth-child(1) > p:nth-child(2)" + ) + .getVisibleText() + .then(function(text) { + assert.match( + text, + /comments:\s\d+$/i, + "Issue should display number of comments" + ); + assert.match( + text, + /^Opened:\s\d{4}\-\d{2}\-\d{2}.+/, + "Issue should display creation date" + ); + }) + .end(); + }, + + "Trying to view someone else's activity fails (logged in)"() { + return FunctionalHelpers.openPage( + this, + url("/activity/someoneelse"), + ".wc-UIContent" + ) + .findByCssSelector(".wc-UIContent .wc-Title--l") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "Forbidden", + "Get a 403 when trying to view someone else's activity" + ); + }) + .end(); + } + } +}); diff --git a/tests/functional/user-activity-non-auth.js b/tests/functional/user-activity-non-auth.js new file mode 100755 index 000000000..da264f610 --- /dev/null +++ b/tests/functional/user-activity-non-auth.js @@ -0,0 +1,33 @@ +"use strict"; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const intern = require("intern").default; +const { assert } = intern.getPlugin("chai"); +const { registerSuite } = intern.getInterface("object"); +const FunctionalHelpers = require("./lib/helpers.js"); + +var url = function(path) { + return intern.config.siteRoot + path; +}; + +registerSuite("User Activity (non-auth)", { + tests: { + "Trying to view someone else's activity fails (logged out)"() { + return FunctionalHelpers.openPage( + this, + url("/activity/someoneelse"), + ".wc-UIContent" + ) + .findByCssSelector(".wc-UIContent .wc-Title--l") + .getVisibleText() + .then(function(text) { + assert.include( + text, + "Unauthorized. Please log in", + "User is told to log in." + ); + }); + } + } +}); diff --git a/tests/javascript/functional/test.js b/tests/javascript/functional/test.js deleted file mode 100644 index 6340aee4c..000000000 --- a/tests/javascript/functional/test.js +++ /dev/null @@ -1,18 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { registerSuite } = intern.getInterface("object"); -const { assert } = intern.getPlugin("chai"); - -registerSuite("Comments (non-auth)", { - whatever() { - return this.remote - .get("http://localhost:5000/issues/200") - .findByCssSelector(".js-Comment-form") - .then(assert.fail, function(err) { - assert.isTrue(/NoSuchElement/.test(String(err))); - }) - .end(); - } -}); diff --git a/tests/javascript/old/comments-auth.js b/tests/javascript/old/comments-auth.js deleted file mode 100644 index 7d4ed9a66..000000000 --- a/tests/javascript/old/comments-auth.js +++ /dev/null @@ -1,154 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Comments (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "Comments form visible when logged in": function() { - return ( - FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") - // Comment form visible for logged in users. - .findDisplayedByCssSelector(".js-Comment-form") - .end() - ); - }, - - "Posting a comment": function() { - var originalCommentsLength; - var allCommentsLength; - return ( - FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") - .findAllByCssSelector(".js-Issue-comment") - .then(function(elms) { - originalCommentsLength = elms.length; - }) - .end() - .findByCssSelector("textarea.js-Comment-text") - .type("Today's date is " + new Date().toDateString()) - .end() - // click the comment button - .findByCssSelector(".js-Issue-comment-button") - .click() - .end() - .sleep(1000) - .findAllByCssSelector(".js-Issue-comment") - .then(function(elms) { - allCommentsLength = elms.length; - assert( - originalCommentsLength < allCommentsLength, - "Comment was successfully left." - ); - }) - ); - }, - - "Posting an empty comment fails": function() { - var originalCommentsLength; - var allCommentsLength; - return ( - FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") - .findAllByCssSelector(".js-Issue-comment") - .then(function(elms) { - originalCommentsLength = elms.length; - }) - .end() - // click the comment button - .findByCssSelector(".js-Issue-comment-button") - .click() - .end() - .sleep(2000) - .findAllByCssSelector(".js-Issue-comment") - .then(function(elms) { - allCommentsLength = elms.length; - assert( - originalCommentsLength === allCommentsLength, - "Comment was not successfully left." - ); - }) - ); - }, - - "Add a screenshot to a comment": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/100"), - ".wc-Comment-body" - ) - .findById("image") - .type("tests/fixtures/green_square.png") - .end() - .sleep(2000) - .findByCssSelector(".js-Comment-text") - .getProperty("value") - .then(function(val) { - assert.include( - val, - "[![Screenshot Description](http://localhost:5000/uploads/", - "The image was correctly uploaded and its URL was copied to the comment text." - ); - }) - .end(); - }, - - "Pressing 'g' inside of comment textarea *doesn't* go to github issue": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/100"), - ".wc-Comment-submit" - ) - .findByCssSelector(".wc-Comment-submit") - .click() - .type("g") - .end() - .setFindTimeout(2000) - .findByCssSelector(".repo-container .issues-listing") - .then(assert.fail, function(err) { - assert.isTrue(/NoSuchElement/.test(String(err))); - }) - .end(); - }, - - "Pressing 'l' inside of comment textarea *doesn't* open the label editor box": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/100"), - ".wc-Comment-submit" - ) - .findByCssSelector(".wc-Comment-submit") - .click() - .type("l") - .end() - .setFindTimeout(2000) - .findByCssSelector(".js-LabelEditorLauncher") - .getAttribute("class") - .then(function(className) { - assert.notInclude(className, "is-active"); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/comments-non-auth.js b/tests/javascript/old/comments-non-auth.js deleted file mode 100644 index 7e525f8a7..000000000 --- a/tests/javascript/old/comments-non-auth.js +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Comments (non-auth)", - - "Comment form not visible for logged out users": function() { - return FunctionalHelpers.openPage(this, url("/issues/200"), ".js-Issue") - .findByCssSelector(".js-Comment-form") - .then(assert.fail, function(err) { - assert.isTrue(/NoSuchElement/.test(String(err))); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/contributors-non-auth.js b/tests/javascript/old/contributors-non-auth.js deleted file mode 100644 index e014198da..000000000 --- a/tests/javascript/old/contributors-non-auth.js +++ /dev/null @@ -1,116 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Contributors", - - "page loads": function() { - return FunctionalHelpers.openPage( - this, - url("/contributors"), - ".wc-Hero--contributors" - ) - .findByCssSelector(".js-Hero-title") - .getVisibleText() - .then(function(text) { - assert.include(text, "Welcome aboard!"); - }) - .end(); - }, - - "clicking first section closes it": function() { - return FunctionalHelpers.openPage( - this, - url("/contributors"), - ".wc-Hero--contributors" - ) - .findByCssSelector(".contributors__item__title") - .click() - .end() - .findByCssSelector(".contributors__item__content") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-open", className); - }) - .end() - .findByCssSelector(".js-Hero-svg") - .getAttribute("class") - .then(function(className) { - assert.notEqual("is-active", className); - }) - .end(); - }, - - "clicking section toggles it": function() { - return FunctionalHelpers.openPage( - this, - url("/contributors"), - ".wc-Hero--contributors" - ) - .findByCssSelector(".contributors__item__content.is-open") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true); - }) - .end() - .findByCssSelector(".js-Hero-svg.is-active") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true); - }) - .end() - .findByCssSelector(".contributors__item__title") - .click() - .end() - .findByCssSelector(".contributors__item__content") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-open", className); - }) - .end() - .findByCssSelector(".js-Hero-svg") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }); - }, - - "toggling section toggles lightbulb": function() { - return FunctionalHelpers.openPage( - this, - url("/contributors"), - ".wc-Hero--contributors" - ) - .findByCssSelector(".js-Hero-svg.is-active") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true); - }) - .end() - .findByCssSelector(".contributors__item__title") - .click() - .end() - .findByCssSelector(".js-Hero-svg") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }); - } - }); - } -); diff --git a/tests/javascript/old/history-navigation-non-auth.js b/tests/javascript/old/history-navigation-non-auth.js deleted file mode 100644 index cc32dc7f5..000000000 --- a/tests/javascript/old/history-navigation-non-auth.js +++ /dev/null @@ -1,48 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "History navigation", - - "Back button works from issues page": function() { - return ( - FunctionalHelpers.openPage(this, url("/"), ".js-issues-link") - .findByCssSelector(".js-issues-link") - .click() - .end() - // check that the page is loaded - .findDisplayedByCssSelector(".wc-IssueList:nth-child(11)") - .end() - .getCurrentUrl() - .then(function(url) { - assert.include(url, "/issues"); - }) - .goBack() - // now check that we're back at the home page. - .findDisplayedByCssSelector(".wc-IssueList:nth-child(1)") - .end() - .getCurrentUrl() - .then(function(url) { - assert.notInclude(url, "/issues"); - }) - .end() - ); - } - }); - } -); diff --git a/tests/javascript/old/image-uploads-non-auth.js b/tests/javascript/old/image-uploads-non-auth.js deleted file mode 100644 index 2914b2302..000000000 --- a/tests/javascript/old/image-uploads-non-auth.js +++ /dev/null @@ -1,212 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*global WindowHelpers:true*/ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers", - "intern/browser_modules/dojo/node!path" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = intern.config.siteRoot + "/?open=1"; - - registerSuite({ - name: "Image Uploads (non-auth)", - - "postMessaged dataURI preview": function() { - return ( - FunctionalHelpers.openPage(this, url, ".js-image-upload-label") - // send a small base64 encoded green test square - .execute( - 'postMessage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAIAAABLixI0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gYSAig452t/EQAAAClJREFUOMvtzkENAAAMg0A25ZU+E032AQEXoNcApCGFLX5paWlpaWl9dqq9AS6CKROfAAAAAElFTkSuQmCC", "http://localhost:5000")' - ) - .sleep(1000) - .findByCssSelector(".js-image-upload-label") - .getAttribute("style") - .then(function(inlineStyle) { - assert.include( - inlineStyle, - "data:image/png;base64,iVBOR", - "Base64 data shown as preview background" - ); - }) - .end() - ); - }, - - "postMessaged blob preview": function() { - return ( - FunctionalHelpers.openPage(this, url, ".js-image-upload-label") - // Build up a green test square in canvas, toBlob that, and then postMessage the blob - // see window-helpers.js for more details. - .execute(function() { - WindowHelpers.getBlob().then(WindowHelpers.sendBlob); - }) - .sleep(1000) - .findByCssSelector(".js-image-upload-label") - .getAttribute("style") - .then(function(inlineStyle) { - assert.include( - inlineStyle, - "data:image/png;base64,iVBOR", - "Base64 data shown as preview background" - ); - }) - .end() - ); - }, - - "uploaded image file preview": function() { - return FunctionalHelpers.openPage(this, url, ".js-image-upload-label") - .findById("image") - .type("tests/fixtures/green_square.png") - .sleep(1000) - .end() - .findByCssSelector(".js-image-upload-label") - .getAttribute("style") - .then(function(inlineStyle) { - assert.include( - inlineStyle, - "data:image/png;base64,iVBOR", - "Base64 data shown as preview background" - ); - }) - .end(); - }, - - "postMessaged dataURI image doesn't upload before form submission": function() { - return ( - FunctionalHelpers.openPage(this, url, ".js-image-upload-label") - // send a small base64 encoded green test square - .execute( - 'postMessage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAIAAABLixI0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gYSAig452t/EQAAAClJREFUOMvtzkENAAAMg0A25ZU+E032AQEXoNcApCGFLX5paWlpaWl9dqq9AS6CKROfAAAAAElFTkSuQmCC", "http://localhost:5000")' - ) - .sleep(1000) - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(val) { - assert.notInclude( - val, - "[![Screenshot Description](http://localhost:5000/uploads/", - "The data URI was not uploaded before form submission." - ); - }) - .end() - ); - }, - - "postMessaged blob image doesn't upload before form submission": function() { - return ( - FunctionalHelpers.openPage(this, url, ".js-image-upload-label") - // Build up a green test square in canvas, toBlob that, and then postMessage the blob - .execute(function() { - WindowHelpers.getBlob().then(WindowHelpers.sendBlob); - }) - .sleep(1000) - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(val) { - assert.notInclude( - val, - "[![Screenshot Description](http://localhost:5000/uploads/", - "The data URI was not uploaded before form submission." - ); - }) - .end() - ); - }, - - "uploaded image file doesn't upload before form submission": function() { - return FunctionalHelpers.openPage(this, url, ".js-image-upload-label") - .findById("image") - .type("tests/fixtures/green_square.png") - .sleep(1000) - .end() - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(val) { - assert.notInclude( - val, - "[![Screenshot Description](http://localhost:5000/uploads/", - "The data URI was not uploaded before form submission." - ); - }) - .end(); - }, - - "remove image upload button": function() { - return ( - FunctionalHelpers.openPage(this, url, ".wc-UploadForm-button") - // send a small base64 encoded green test square - .execute( - 'postMessage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAIAAABLixI0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gYSAig452t/EQAAAClJREFUOMvtzkENAAAMg0A25ZU+E032AQEXoNcApCGFLX5paWlpaWl9dqq9AS6CKROfAAAAAElFTkSuQmCC", "http://localhost:5000")' - ) - .sleep(1000) - .findByCssSelector(".js-image-upload-label .wc-UploadForm-button") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "Remove button is displayed"); - }) - .end() - .findByCssSelector(".js-image-upload-label .wc-UploadForm-button") - .click() - .sleep(1000) - .end() - .findByCssSelector(".js-image-upload-label") - .getAttribute("style") - .then(function(inlineStyle) { - assert.notInclude( - inlineStyle, - "data:image/png;base64,iVBOR", - "Preview was removed" - ); - }) - .end() - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(val) { - assert.notInclude( - val, - "[![Screenshot Description](http://localhost:5000/uploads/", - "The url to the image upload was correctly removed." - ); - }) - .end() - ); - }, - - "double image select works": function() { - return FunctionalHelpers.openPage(this, url, ".wc-UploadForm-button") - .findById("image") - .type("tests/fixtures/green_square.png") - .sleep(1000) - .end() - .findByCssSelector(".js-image-upload-label .wc-UploadForm-button") - .click() - .sleep(1000) - .end() - .findById("image") - .type("tests/fixtures/green_square.png") - .end() - .sleep(1000) - .findByCssSelector(".js-image-upload-label") - .getAttribute("style") - .then(function(inlineStyle) { - assert.include( - inlineStyle, - "data:image/png;base64,iVBOR", - "Preview is shown" - ); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/index-non-auth.js b/tests/javascript/old/index-non-auth.js deleted file mode 100644 index f118f4cc9..000000000 --- a/tests/javascript/old/index-non-auth.js +++ /dev/null @@ -1,128 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Index", - - "front page loads": function() { - return FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") - .findByCssSelector(".js-Hero-title") - .getVisibleText() - .then(function(text) { - assert.equal(text, "Bug reporting\nfor the internet."); - }) - .end(); - }, - - "reporter addon link is shown": function() { - return FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") - .findByCssSelector(".js-Navbar-link") - .getVisibleText() - .then(function(text) { - assert.include(text, "Download our"); - }) - .end(); - }, - - "form toggles open then closed": function() { - return ( - FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") - .findByCssSelector("#js-ReportBug") - .click() - .end() - .sleep(1000) - .findByCssSelector("#js-ReportForm") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "The form is displayed"); - }) - .end() - .findByCssSelector("#js-ReportBug") - .click() - .end() - // wait a bit for animation to finish - .sleep(1000) - .findByCssSelector("#js-ReportForm") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, false, "The form should be hidden"); - }) - ); - }, - - "browse issues (needstriage)": function() { - return FunctionalHelpers.openPage(this, url("/"), ".js-Hero-title") - .findAllByCssSelector( - "#js-lastIssue .js-IssueList.wc-IssueList--needstriage" - ) - .then(function(elms) { - assert.equal(elms.length, 10, "10 issues should be displayed"); - }) - .end() - .findByCssSelector(".wc-IssueList--needstriage .wc-IssueList-count") - .getVisibleText() - .then(function(text) { - assert.match(text, /^Issue\s(\d+)$/, "Issue should have a number"); - }) - .end() - .findByCssSelector( - ".wc-IssueList--needstriage .wc-IssueList-header a" - ) - .getAttribute("href") - .then(function(text) { - assert.match(text, /^\/issues\/\d+$/, "Link should have a number"); - }) - .end() - .findByCssSelector(".wc-IssueList--needstriage .wc-IssueList-header") - .getVisibleText() - .then(function(text) { - assert.match( - text, - /^Issue\s\d+:\s.+$/, - "Issue should have a non-empty title" - ); - }) - .end() - .findByCssSelector( - ".wc-IssueList--needstriage .wc-IssueList-metadata:nth-child(1)" - ) - .getVisibleText() - .then(function(text) { - assert.match( - text, - /^Opened:\s\d{4}\-\d{2}\-\d{2}/, - "Issue should display creation date" - ); - }) - .end() - .findByCssSelector( - ".wc-IssueList--needstriage .wc-IssueList-metadata:nth-child(2)" - ) - .getVisibleText() - .then(function(text) { - assert.match( - text, - /Comments:\s\d/, - "Issue should display number of comments" - ); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/issue-list-non-auth.js b/tests/javascript/old/issue-list-non-auth.js deleted file mode 100644 index ecc787732..000000000 --- a/tests/javascript/old/issue-list-non-auth.js +++ /dev/null @@ -1,452 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path, params) { - var base = intern.config.siteRoot + path; - return params ? base + params : base; - }; - - registerSuite({ - name: "Issue-list", - - "FilterView renders": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-SearchIssue-filter" - ) - .findAllByCssSelector("button.js-Tag") - .then(function(elms) { - assert.equal(elms.length, 6, "All filter buttons are displayed"); - }) - .end(); - }, - - "IssueListView renders": function() { - return FunctionalHelpers.openPage(this, url("/issues"), ".js-IssueList") - .findByCssSelector(".js-IssueList") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "IssueList container is visible."); - }) - .sleep(1000) - .end() - .findByCssSelector(".js-list-issue .js-IssueList") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "IssueList item is visible."); - }) - .end() - .findByCssSelector(".js-IssueList .wc-IssueList-header") - .getVisibleText() - .then(function(text) { - assert.match( - text, - /^Issue\s\d+:\s.+$/, - "Issue should have a non-empty title" - ); - }) - .end() - .findByCssSelector( - ".js-IssueList:nth-child(1) > div:nth-child(1) > p:nth-child(2)" - ) - .getVisibleText() - .then(function(text) { - assert.match( - text, - /comments:\s\d+$/i, - "Issue should display number of comments" - ); - assert.match( - text, - /^Opened:\s\d{4}\-\d{2}\-\d{2}.+/, - "Issue should display creation date" - ); - }) - .end(); - }, - - "PaginationControlsView tests": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-Pagination-controls" - ) - .findByCssSelector(".js-Pagination-controls") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "IssueList container is visible."); - }) - .end() - .findByCssSelector(".js-Pagination-previous.is-disabled") - .getAttribute("class") - .then(function(className) { - assert.include( - className, - "is-disabled", - "First page load should have disabled prev button" - ); - }) - .end() - .findByCssSelector(".js-Pagination-next") - .click() - .end() - .findByCssSelector(".js-Pagination-previous:not(.is-disabled)") - .getAttribute("class") - .then(function(className) { - assert.notInclude( - className, - "is-disabled", - "Clicking next enables prev button" - ); - }) - .end() - .findByCssSelector(".js-Pagination-previous") - .click() - .end() - .findByCssSelector(".js-Pagination-previous.is-disabled") - .getAttribute("class") - .then(function(className) { - assert.include( - className, - "is-disabled", - "Going back from first next click should have disabled prev button" - ); - }) - .end(); - }, - - "Pagination dropdown tests": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-Pagination-controls" - ) - .findByCssSelector(".js-Dropdown-pagination") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal( - isDisplayed, - true, - "pagination dropdown container is visible." - ); - }) - .end() - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle") - .click() - .end() - .findByCssSelector(".js-Dropdown-pagination") - .getAttribute("class") - .then(function(className) { - assert.include( - className, - "is-active", - "clicking dropdown adds is-active class" - ); - }) - .end() - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-options") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "dropdown options are visible."); - }) - .end() - .findByCssSelector( - ".js-Dropdown-pagination .js-Dropdown-item:nth-child(3) > .js-Dropdown-link:nth-child(1)" - ) - .click() - .end() - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-label") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "Show 100", - "Clicking first option updated dropdown label" - ); - }) - .end() - .findDisplayedByCssSelector(".js-IssueList:nth-child(51)") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "More than 50 issues were loaded."); - }) - .end(); - }, - - "Pressing g goes to github issues": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-Pagination-controls" - ) - .pressKeys("g") - .end() - .sleep(500) - .getCurrentUrl() - .then(function(url) { - assert.match( - url, - /[https://github.com/^*/^*/issues/]/, - "We're at GitHub now." - ); - }) - .end(); - }, - - "Pressing g inside of search input *doesn't* go to github issues": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - "#js-SearchForm-input" - ) - .findByCssSelector("#js-SearchForm-input") - .click() - .type("g") - .end() - .setFindTimeout(0) - .findByCssSelector(".repo-container .issues-listing") - .then(assert.fail, function(err) { - assert.isTrue(/NoSuchElement/.test(String(err))); - }) - .end(); - }, - - "Loading issues page has default params in URL": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-IssueList:nth-of-type(1)" - ) - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "page=1&per_page=50&state=open", - "Default model params are added to the URL" - ); - }); - }, - - "Loading partial params results in merge with defaults": function() { - var params = "?page=2"; - return FunctionalHelpers.openPage( - this, - url("/issues", params), - ".js-IssueList:nth-of-type(1)" - ) - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "page=2&per_page=50&state=open", - "Default model params are merged with partial URL params" - ); - }); - }, - - "Dropdowns reflect state from URL": function() { - var params = "?per_page=25&sort=updated&direction=desc&state=all"; - - return FunctionalHelpers.openPage( - this, - url("/issues", params), - ".js-IssueList:nth-of-type(1)" - ) - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle h1") - .getVisibleText() - .then(function(text) { - assert.equal( - text, - "Show 25", - "Pagination dropdown label is updated from URL params" - ); - }) - .end() - .findAllByCssSelector(".js-Dropdown-sort .js-Dropdown-toggle h1") - .getVisibleText() - .then(function(text) { - assert.equal( - text, - "Recently Updated", - "Sort dropdown label is updated from URL params" - ); - }) - .end(); - }, - - "Going back in history updates issue list and URL state": function() { - var params = "?per_page=25"; - - return ( - FunctionalHelpers.openPage( - this, - url("/issues", params), - ".js-IssueList:nth-of-type(1)" - ) - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle h1") - .getVisibleText() - .then(function(text) { - assert.equal( - text, - "Show 25", - "Pagination dropdown label is updated from URL params" - ); - }) - .end() - // Select "Show 100" from pagination dropdown - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle") - .click() - .end() - .findByCssSelector( - ".js-Dropdown-pagination li.js-Dropdown-item:nth-child(3) > a:nth-child(1)" - ) - .click() - .end() - // find something so we know issues have been loaded - .findByCssSelector(".js-IssueList:nth-of-type(1)") - .execute(function() { - history.back(); - }) - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "per_page=25", - "URL param is back to where we started" - ); - }) - .end() - .findByCssSelector(".js-Dropdown-pagination .js-Dropdown-toggle h1") - .getVisibleText() - .then(function(text) { - assert.equal( - text, - "Show 25", - "Pagination dropdown label is back to where we started" - ); - }) - .end() - ); - }, - - "Loading URL with stage param loads issues": function() { - var params = - "?page=1&per_page=50&state=open&stage=needstriage&sort=created&direction=desc"; - - return FunctionalHelpers.openPage( - this, - url("/issues", params), - ".js-IssueList:nth-of-type(1)" - ) - .findByCssSelector(".js-Tag.is-active") - .getVisibleText() - .then(function(text) { - assert.equal( - "Needs Triage", - text, - "Needs Triage filter is selected." - ); - }) - .end(); - }, - - "Clicking on a stage filter adds the correct param to the URL": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-IssueList:nth-of-type(1)" - ) - .findByCssSelector('[data-filter="contactready"]') - .click() - .end() - // find something so we know the page has loaded - .findByCssSelector(".wc-IssueList:nth-of-type(1)") - .end() - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "stage=contactready", - "Stage filter added to URL correctly." - ); - }) - .end() - ); - }, - - "Toggling a stage filter doesn't leave the param in the URL": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-IssueList:nth-of-type(1)" - ) - .findByCssSelector('[data-filter="closed"]') - .click() - .end() - // find something so we know the page has loaded - .findByCssSelector(".wc-IssueList:nth-of-type(1)") - .end() - .findByCssSelector('[data-filter="closed"]') - .click() - .end() - .getCurrentUrl() - .then(function(currUrl) { - assert.notInclude( - currUrl, - "stage=closed", - "Stage filter added then removed from URL." - ); - }) - .end() - ); - }, - - "Toggling between stage filters results in last param in URL": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-IssueList:nth-of-type(1)" - ) - .findByCssSelector('[data-filter="closed"]') - .click() - .end() - // find something so we know the page has loaded - .findByCssSelector(".wc-IssueList:nth-of-type(1)") - .end() - .findByCssSelector('[data-filter="sitewait"]') - .click() - .end() - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "stage=sitewait", - "Stage filter added to URL correctly." - ); - assert.notInclude( - currUrl, - "stage=closed", - "Stage removed from URL correctly." - ); - }) - .end() - ); - } - }); - } -); diff --git a/tests/javascript/old/issues-auth.js b/tests/javascript/old/issues-auth.js deleted file mode 100644 index 7e7ca4123..000000000 --- a/tests/javascript/old/issues-auth.js +++ /dev/null @@ -1,48 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Issues (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "Pressing 'l' opens the label editor box": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/70"), - ".wc-Issue-commentSubmit" - ) - .pressKeys("l") - .end() - .findByCssSelector(".js-LabelEditorLauncher") - .then(function(element) { - element.getAttribute("class").then(function(classList) { - assert.include(classList, "is-active"); - }); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/issues-non-auth.js b/tests/javascript/old/issues-non-auth.js deleted file mode 100644 index 473a67260..000000000 --- a/tests/javascript/old/issues-non-auth.js +++ /dev/null @@ -1,124 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Issues", - - "Issue page loads": function() { - return FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") - .findDisplayedByCssSelector(".wc-Issue-information-header") - .getVisibleText() - .then(function(text) { - assert.include(text, "#100", "Issue title displayed"); - }) - .end() - .findByCssSelector(".js-Issue-reporter") - .getVisibleText() - .then(function(text) { - assert.equal(text, "miketaylr", "Issue reporter displayed."); - }) - .end() - .findByCssSelector(".js-Label") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true); - }); - }, - - "Issue comments load": function() { - return FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") - .findDisplayedByCssSelector(".js-Issue-comment") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true); - }) - .findByCssSelector(".js-Comment-owner") - .getVisibleText() - .then(function(text) { - assert.equal(text, "GIGANTOR", "Commenter name displayed."); - }) - .end() - .findByCssSelector(".js-Comment-content") - .getVisibleText() - .then(function(text) { - assert.equal( - text, - "Today's date is Mon Sep 28 2015", - "Comment is displayed." - ); - }); - }, - - "Pressing g goes to the github issue page": function() { - return FunctionalHelpers.openPage(this, url("/issues/100"), ".js-Issue") - .pressKeys("g") - .end() - .sleep(500) - .getCurrentUrl() - .then(function(url) { - assert.match( - url, - /[https://github.com/^*/^*/issues/100]/, - "We're at the GitHub issue page now." - ); - }); - }, - - "NSFW images are blurred": function() { - return FunctionalHelpers.openPage(this, url("/issues/396"), ".js-Issue") - .findDisplayedByCssSelector( - ".js-Issue-commentList .js-Comment-content p" - ) - .getAttribute("class") - .then(function(className) { - assert.include(className, "wc-Comment-content-nsfw"); - }) - .end(); - }, - - "Clicking NSFW images toggles between blurry and not-blurry": function() { - return FunctionalHelpers.openPage(this, url("/issues/396"), ".js-Issue") - .findDisplayedByCssSelector( - ".js-Issue-commentList .js-Comment-content p" - ) - .getAttribute("class") - .then(function(className) { - assert.include(className, "wc-Comment-content-nsfw"); - assert.notInclude(className, "wc-Comment-content-nsfw--display"); - }) - .click() - .end() - .findByCssSelector(".js-Issue-commentList .js-Comment-content p") - .getAttribute("class") - .then(function(className) { - assert.include(className, "wc-Comment-content-nsfw"); - assert.include(className, "wc-Comment-content-nsfw--display"); - }) - .click() - .end() - .findByCssSelector(".js-Issue-commentList .js-Comment-content p") - .getAttribute("class") - .then(function(className) { - assert.include(className, "wc-Comment-content-nsfw"); - assert.notInclude(className, "wc-Comment-content-nsfw--display"); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/labels-auth.js b/tests/javascript/old/labels-auth.js deleted file mode 100644 index 9808f5d8e..000000000 --- a/tests/javascript/old/labels-auth.js +++ /dev/null @@ -1,121 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers", - "intern/dojo/node!leadfoot/keys" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers, keys) { - "use strict"; - registerSuite(function() { - var url = function(path) { - return intern.config.siteRoot + path; - }; - - return { - name: "Labels (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "Label editor opens then closes (clicks)": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-LabelEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector(".js-LabelEditorLauncher") - .click() - .end() - .findByCssSelector(".js-CategoryEditor") - .end() - .findByCssSelector(".js-LabelEditorLauncher") - .click() - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - }, - - "Label editor opens then closes (key events)": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-LabelEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector("body") - .type("l") - .end() - .findByCssSelector(".wc-CategoryEditor-search") - .type(keys.ESCAPE) - .end() - .findByCssSelector(".js-LabelEditorLauncher") - .click() - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - }, - - "Clicking outside label editor closes it": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-LabelEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector(".js-LabelEditorLauncher") - .click() - .end() - .findByCssSelector(".js-CategoryEditor") - .end() - .findByCssSelector("main") - .click() - .end() - .findByCssSelector(".js-LabelEditorLauncher") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - }, - - "Clicking close button actually closes it?": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-LabelEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector(".js-LabelEditorLauncher") - .click() - .end() - .findByCssSelector(".js-CategoryEditor-close") - .click() - .end() - .findByCssSelector(".js-LabelEditorLauncher") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - } - }; - }); - } -); diff --git a/tests/javascript/old/lib/helpers.js b/tests/javascript/old/lib/helpers.js deleted file mode 100644 index ae9bd7043..000000000 --- a/tests/javascript/old/lib/helpers.js +++ /dev/null @@ -1,111 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*eslint no-console: ["error", { allow: ["log", "error"] }] */ - -define( - ["intern", "intern!object", "require", "intern/dojo/node!http"], - function(intern, registerSuite, require, http) { - "use strict"; - var config = intern.config; - - var url = function(path, params) { - var base = intern.config.siteRoot + path; - return params ? base + params : base; - }; - - /* - Use this method to make sure a page is loaded before trying to find - things inside of it. The optional boolean longer arg at the end can - be used for tests that need more time. - */ - function openPage(context, url, readySelector, longerTimeout) { - var timeout = longerTimeout ? 20000 : config.wc.pageLoadTimeout; - - return ( - context.remote - .get(require.toUrl(url)) - .setFindTimeout(timeout) - // Wait until the `readySelector` element is found to return. - .findByCssSelector(readySelector) - .end() - .then(null, function(err) { - return context.remote - .getCurrentUrl() - .then(function(resultUrl) { - console.log("Error fetching %s", resultUrl); - }) - .end() - .then(function() { - throw err; - }); - }) - ); - } - - /* - This method makes a call to our API to check that the server is returning fixture data, - it will also check if there's anything wrong with the server. - */ - function checkServer() { - return new Promise(function(resolve, reject) { - var request = http.get(url("/api/issues/100"), function(response) { - response.on("data", function(data) { - var json = JSON.parse(data); - if (!json.hasOwnProperty("_fixture")) { - reject( - new Error( - ` - ======================================================= - It seems like you didn't start the server in test mode. - Open another terminal and window type: - \x1b[32m npm run start:test\x1b[0m - or - \x1b[32m python run.py -t\x1b[0m - ======================================================= - ` - ) - ); - } else { - resolve("All is well!"); - } - }); - }); - - // Handle connection errors. - request.on("error", function() { - reject( - new Error( - ` - ====================================================== - Oops, something went wrong. Try restarting the server. - Open another terminal and window type: - \x1b[32m npm run start:test\x1b[0m - or - \x1b[32m python run.py -t\x1b[0m - ====================================================== - ` - ) - ); - }); - request.end(); - }); - } - - function login(context) { - return openPage(context, url("/login"), "body").end(); - } - - function logout(context) { - return openPage(context, url("/logout"), "body").clearCookies().end(); - } - - return { - openPage: openPage, - checkServer: checkServer, - login: login, - logout: logout - }; - } -); diff --git a/tests/javascript/old/milestones-auth.js b/tests/javascript/old/milestones-auth.js deleted file mode 100644 index dd7e43225..000000000 --- a/tests/javascript/old/milestones-auth.js +++ /dev/null @@ -1,121 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers", - "intern/dojo/node!leadfoot/keys" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers, keys) { - "use strict"; - registerSuite(function() { - var url = function(path) { - return intern.config.siteRoot + path; - }; - - return { - name: "Milestones (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "Milestone editor opens then closes (clicks)": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-MilestoneEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector(".js-MilestoneEditorLauncher") - .click() - .end() - .findByCssSelector(".js-CategoryEditor") - .end() - .findByCssSelector(".js-MilestoneEditorLauncher") - .click() - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - }, - - "Milestone editor opens then closes (key events)": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-MilestoneEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector("body") - .type("m") - .end() - .findByCssSelector(".wc-CategoryEditor-search") - .type(keys.ESCAPE) - .end() - .findByCssSelector(".js-MilestoneEditorLauncher") - .click() - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - }, - - "Clicking outside milestone editor closes it": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-MilestoneEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector(".js-MilestoneEditorLauncher") - .click() - .end() - .findByCssSelector(".js-CategoryEditor") - .end() - .findByCssSelector("main") - .click() - .end() - .findByCssSelector(".js-MilestoneEditorLauncher") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - }, - - "Clicking close button actually closes it?": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/2"), - ".js-MilestoneEditorLauncher", - true /* longerTimeout */ - ) - .findByCssSelector(".js-MilestoneEditorLauncher") - .click() - .end() - .findByCssSelector(".js-CategoryEditor-close") - .click() - .end() - .findByCssSelector(".js-MilestoneEditorLauncher") - .getAttribute("class") - .then(function(className) { - assert.notInclude("is-active", className); - }) - .end(); - } - }; - }); - } -); diff --git a/tests/javascript/old/milestones-non-auth.js b/tests/javascript/old/milestones-non-auth.js deleted file mode 100644 index fcb46b7d7..000000000 --- a/tests/javascript/old/milestones-non-auth.js +++ /dev/null @@ -1,57 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - registerSuite(function() { - var url = function(path) { - return intern.config.siteRoot + path; - }; - - return { - name: "Milestones (non-auth)", - - "Page loads without milestone set": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/9"), - ".js-Issue", - true /* longerTimeout */ - ) - .findByCssSelector(".js-Issue-title") - .getVisibleText() - .then(function(text) { - // check that the title loaded, it won't be there if the page didn't render. - assert.include(text, "No Milestone."); - }) - .end(); - }, - - "Missing status error displays": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/9"), - ".js-Issue", - true /* longerTimeout */ - ) - .findByCssSelector(".js-Milestone") - .getVisibleText() - .then(function(text) { - // check that the title loaded, it won't be there if the page didn't render. - assert.equal(text, "Error: no status for this issue"); - }) - .end(); - } - }; - }); - } -); diff --git a/tests/javascript/old/new-issue-non-auth.js b/tests/javascript/old/new-issue-non-auth.js deleted file mode 100644 index cea303f98..000000000 --- a/tests/javascript/old/new-issue-non-auth.js +++ /dev/null @@ -1,38 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "New Issue Page", - - "new issue page loads": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".js-Navbar-link" - ) - .findByCssSelector(".js-Navbar-link") - .getVisibleText() - .then(function(text) { - assert.equal(text, "Home"); - assert.notInclude(text, "Download our"); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/reporting-auth.js b/tests/javascript/old/reporting-auth.js deleted file mode 100644 index 20da7106c..000000000 --- a/tests/javascript/old/reporting-auth.js +++ /dev/null @@ -1,45 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Reporting (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "Report button shows name": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".js-Navbar-link" - ) - .findByCssSelector("#submitgithub") - .getVisibleText() - .then(function(text) { - assert.include(text, "Report as"); //Report as FooUser (logged in) - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/reporting-non-auth.js b/tests/javascript/old/reporting-non-auth.js deleted file mode 100644 index 2dc411e84..000000000 --- a/tests/javascript/old/reporting-non-auth.js +++ /dev/null @@ -1,329 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "intern/browser_modules/dojo/node!path", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, path, FunctionalHelpers) { - "use strict"; - var cwd = intern.config.basePath; - var VALID_IMAGE_PATH = path.join(cwd, "tests/fixtures", "green_square.png"); - var BAD_IMAGE_PATH = path.join(cwd, "tests/fixtures", "evil.py"); - var DETAILS_STRING = - "Encountered error: NS_ERROR_DOM_MEDIA_DEMUXER_ERR (0x806e000c)%0ALocation: virtual%0ARefPtrMP4Demuxer::InitPromise mozilla::MP4Demuxer::Init()%0AError information:%0AIncomplete MP4 metadata%0AMedia URL: file:///Users/potch/Documents/mozilla/media.mp4"; - var DETAILS_STRING2 = "Encountered+error:+NS_ERROR_DOM_MEDIA_DEMUXER_ERR"; - - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "Reporting (non-auth)", - - "Submit buttons are disabled": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - .findAllByCssSelector(".wc-ReportForm-actions-button button") - .getAttribute("class") - .then(function(classNames) { - classNames.forEach(function(className) { - assert.include(className, "is-disabled"); - }); - }) - .end(); - }, - - "Wyciwyg bug workaround": function() { - return FunctionalHelpers.openPage( - this, - url( - "/issues/new?url=wyciwyg://0/http://bbs.csdn.net/topics/20282413" - ), - "#url" - ) - .findByCssSelector("#url") - .getProperty("value") - .then(function(value) { - assert.notInclude(value, "wyciwyg://0/"); - }) - .end(); - }, - - "Report button shows via GitHub": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - .findByCssSelector("#submitgithub") - .getVisibleText() - .then(function(text) { - assert.include(text, "Report via"); //Report via GitHub (logged out) - }) - .end(); - }, - - "URL validation": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - .findByCssSelector("#url") - .click() - .end() - .execute(function() { - var elm = document.querySelector("#url"); - WindowHelpers.sendEvent(elm, "input"); - }) - .sleep(500) - .findByCssSelector(".wc-Form-helpMessage") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "A valid URL is required", - "URL validation message is shown" - ); - }) - .end() - .findByCssSelector("#url") - .type("sup") - .end() - .waitForDeletedByCssSelector(".wc-Form-helpMessage") - .end(); - }, - - "Description validation": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - .findByCssSelector("#description") - .click() - .end() - .execute(function() { - var elm = document.querySelector("#description"); - WindowHelpers.sendEvent(elm, "input"); - }) - .sleep(500) - .findByCssSelector(".wc-Form-helpMessage") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "Description required.", - "Description validation message is shown" - ); - }) - .end() - // enter a bug description - .findByCssSelector("#description") - .type("bug description") - .end() - // validation message should be gone - .waitForDeletedByCssSelector(".wc-Form-helpMessage") - .end() - ); - }, - - "(optional) browser + os validation": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - // make sure we can see the valid checkbox (i.e. it's background image is non-empty) - .execute(function() { - return window - .getComputedStyle( - document.querySelector(".js-bug-form-os"), - ":after" - ) - .getPropertyValue("background-image"); - }) - .then(function(bgImage) { - assert.include( - bgImage, - "valid.svg", - "The valid checkbox pseudo is visible" - ); - }) - .end() - .execute(function() { - var elm = document.querySelector("#os"); - elm.value = ""; - WindowHelpers.sendEvent(elm, "input"); - }) - .end() - .sleep(500) - // make sure we can't see the valid checkbox (i.e. it's background image is empty) - .execute(function() { - return window - .getComputedStyle( - document.querySelector(".js-bug-form-os"), - ":after" - ) - .getPropertyValue("background-image"); - }) - .then(function(bgImage) { - assert.notInclude( - bgImage, - "valid.svg", - "The valid checkbox pseudo is not visible" - ); - }) - .end() - ); - }, - - "Image extension validation": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - .findByCssSelector("#image") - .type(BAD_IMAGE_PATH) - .end() - .findByCssSelector(".wc-Form-helpMessage--imageUpload") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "Image must be one of the following", - "Image type validation message is shown" - ); - }) - .end() - // pick a valid file type - .findByCssSelector("#image") - .type(VALID_IMAGE_PATH) - .end() - // validation message should be gone - .waitForDeletedByCssSelector(".wc-Form-helpMessage--imageUpload") - .end() - ); - }, - - "Submits are enabled": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues/new"), - ".wc-ReportForm-actions-button" - ) - // pick a valid file type - .findByCssSelector("#image") - .type(VALID_IMAGE_PATH) - .end() - .findByCssSelector("#url") - .type("http://coolguy.biz") - .end() - // pick a problem type - .findByCssSelector("#problem_category-0") - .click() - .end() - .findByCssSelector("#description") - .type("test for desktop site") - //.click() - .end() - // wait a bit - .sleep(250) - // now make sure the buttons aren't disabled anymore - .findAllByCssSelector(".wc-ReportForm-actions-button button") - .getAttribute("class") - .then(function(classNames) { - classNames.forEach(function(className) { - assert.notInclude(className, "is-disabled"); - }); - }) - .end() - ); - }, - - // tests a scenario where bug reported from firefox nightly media type tool - "problem_type param selects problem type": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new?problem_type=video_bug"), - ".wc-ReportForm-actions-button" - ) - .findByCssSelector("[value=video_bug]") - .isSelected() - .then(function(isSelected) { - assert.isTrue(isSelected, "The right option is selected"); - }) - .end(); - }, - - "details param adds info to description": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new?details=" + DETAILS_STRING), - "#description" - ) - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(text) { - assert.include( - text, - "Encountered error: NS_ERROR_DOM_MEDIA_DEMUXER_ERR (0x806e000c)\nLocation: virtual\nRefPtrMP4Demuxer::InitPromise mozilla::MP4Demuxer::Init()\nError information:\nIncomplete MP4 metadata\nMedia URL: file:///Users/potch/Documents/mozilla/media.mp4" - ); - }) - .end(); - }, - - "multiple details params add info to description": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new?details=" + DETAILS_STRING + "&details=wowow"), - "#description" - ) - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(text) { - assert.include(text, "NS_ERROR_DOM_MEDIA_DEMUXER_ERR"); - assert.include(text, "wowow"); - }) - .end(); - }, - - "details param: + decoded as space": function() { - return FunctionalHelpers.openPage( - this, - url("/issues/new?details=" + DETAILS_STRING2), - "#description" - ) - .findByCssSelector("#steps_reproduce") - .getProperty("value") - .then(function(text) { - assert.notInclude( - text, - "Encountered+error:+NS_ERROR_DOM_MEDIA_DEMUXER_ERR", - "+ not found in decoded string" - ); - assert.include( - text, - "Encountered error: NS_ERROR_DOM_MEDIA_DEMUXER_ERR", - "+ replaced with space" - ); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/search-auth.js b/tests/javascript/old/search-auth.js deleted file mode 100644 index 02ea6b38c..000000000 --- a/tests/javascript/old/search-auth.js +++ /dev/null @@ -1,230 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers", - "intern/dojo/node!leadfoot/keys" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers, keys) { - "use strict"; - var url = function(path, params) { - var fullUrl = params !== undefined - ? intern.config.siteRoot + path + params - : intern.config.siteRoot + path; - return fullUrl; - }; - - registerSuite({ - name: "Search (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "Search/filter interaction": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".wc-SearchForm-item" - ) - .findDisplayedByCssSelector(".wc-SearchForm-item") - .click() - .type("taco") - .end() - .findAllByCssSelector("button.wc-Tag--needstriage") - .click() - .end() - .findByCssSelector(".wc-SearchForm-item") - .getVisibleText() - .then(function(text) { - assert.equal(text, "", "Clicking filter should empty search text"); - }) - .end() - .findAllByCssSelector("button.wc-Tag--needstriage") - .click() - .end() - .findByCssSelector(".wc-SearchForm-item") - .click() - .type("taco") - .end() - .findAllByCssSelector("button.wc-Tag--needstriage") - .getAttribute("class") - .then(function(className) { - assert.notInclude( - className, - "is-active", - "Searching should clear all filters" - ); - }) - .end(); - }, - - "Results are loaded from the query params": function() { - var params = - "?page=1&per_page=50&state=open&stage=all&sort=created&direction=desc&q=vladvlad"; - return FunctionalHelpers.openPage( - this, - url("/issues", params), - ".wc-IssueList:nth-of-type(1)" - ) - .findDisplayedByCssSelector(".wc-IssueList:nth-of-type(1) .wc-Link") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "vladvlad", - "The search query results show up on the page." - ); - }) - .end() - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "q=vladvlad", - "Our params didn't go anywhere." - ); - }) - .end(); - }, - - "Search works by icon click": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".wc-IssueList:nth-of-type(10)" - ) - .findByCssSelector(".js-SearchForm input") - .type("vladvlad") - .end() - .findByCssSelector(".js-SearchForm button") - .click() - .end() - .findDisplayedByCssSelector(".wc-IssueList:only-of-type a") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "vladvlad", - "The search results show up on the page." - ); - }) - .end(); - }, - - "Search works by Return key": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-SearchForm input" - ) - .findDisplayedByCssSelector(".js-SearchForm input") - .type("vladvlad") - .type(keys.ENTER) - .end() - .findDisplayedByCssSelector(".wc-IssueList:only-of-type a") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "vladvlad", - "The search results show up on the page." - ); - }) - .end(); - }, - - "Search from the homepage": function() { - return ( - FunctionalHelpers.openPage(this, url("/"), ".js-SearchBarOpen") - .get(require.toUrl(url("/"))) - .findByCssSelector(".js-SearchBarOpen") - .click() - .end() - // Wait for animation to complete. - .sleep(1000) - .findByCssSelector(".js-SearchBar input") - .click() - .type("vladvlad") - .type(keys.ENTER) - .end() - .findDisplayedByCssSelector(".wc-IssueList:only-of-type a") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "vladvlad", - "The search query results show up on the page." - ); - }) - .end() - .getCurrentUrl() - .then(function(currUrl) { - assert.include(currUrl, "page=1", "Default params got merged."); - }) - .end() - ); - }, - - "Search with a dash works": function() { - // load up a garbage search, so we can more easily detect when - // the search values we want are loaded. - var searchParam = "?q=jfdkjfkdjfkdjfdkjfkd"; - return FunctionalHelpers.openPage( - this, - url("/issues", searchParam), - ".wc-SearchIssue-noResults-title" - ) - .findByCssSelector("#js-SearchForm-input") - .clearValue() - .click() - .type("label:status-tacos") - .type(keys.ENTER) - .end() - .findDisplayedByCssSelector( - ".wc-IssueList:first-of-type .js-Issue-label" - ) - .getVisibleText() - .then(function(text) { - assert.include( - text, - "tacos", - "The label:status-tacos search worked." - ); - }) - .end(); - }, - - "Search input is loaded from q param (with dashes)": function() { - // load up a garbage search, so we can more easily detect when - // the search values we want are loaded. - var searchParam = "?q=one:two-three"; - return FunctionalHelpers.openPage( - this, - url("/issues", searchParam), - ".wc-SearchIssue-noResults-title" - ) - .findByCssSelector("#js-SearchForm-input") - .getProperty("value") - .then(function(text) { - assert.include( - text, - "one:two-three", - "The q param populated the search input." - ); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/search-non-auth.js b/tests/javascript/old/search-non-auth.js deleted file mode 100644 index a4f835dae..000000000 --- a/tests/javascript/old/search-non-auth.js +++ /dev/null @@ -1,132 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers", - "intern/dojo/node!leadfoot/keys" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers, keys) { - "use strict"; - var url = function(path, params) { - var base = intern.config.siteRoot + path; - return params ? base + params : base; - }; - - registerSuite({ - name: "Search (non-auth)", - - "Pressing g inside of search input *doesnt* go to github issues": function() { - return ( - FunctionalHelpers.openPage( - this, - url("/issues"), - "#js-SearchForm-input" - ) - .findByCssSelector("#js-SearchForm-input") - .click() - .type("g") - .end() - // set a short timeout, so we don't have to wait 10 seconds - // to realize we're not at GitHub. - .setFindTimeout(0) - .findByCssSelector(".repo-container .issues-listing") - .then(assert.fail, function(err) { - assert.isTrue(/NoSuchElement/.test(String(err))); - }) - .end() - ); - }, - - "Clicking on label search adds query parameter to the URL": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - "[data-remotename=browser-android" - ) - .findByCssSelector("[data-remotename=browser-android]") - .click() - .end() - .getCurrentUrl() - .then(function(currUrl) { - assert.include( - currUrl, - "q=label%3Abrowser-android", - "Url updated with label name" - ); - }) - .end(); - }, - - "Clicking on label search updates the search input": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - "[data-remotename=browser-android" - ) - .findByCssSelector("[data-remotename=browser-android]") - .click() - .end() - .findDisplayedById("js-SearchForm-input") - .getProperty("value") - .then(function(searchText) { - assert.include( - searchText, - "label:browser-android", - "Url updated with label name" - ); - }) - .end(); - }, - - "Search input is visible": function() { - return FunctionalHelpers.openPage( - this, - url("/issues"), - ".js-SearchForm" - ) - .findByCssSelector(".js-SearchForm") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal( - isDisplayed, - true, - "Search input is visible for non-authed users." - ); - }) - .end(); - }, - - "Empty search input removes q param": function() { - // load up a garbage search, so we can more easily detect when - // the search values we want are loaded. - var searchParam = "?q=fffffff"; - return FunctionalHelpers.openPage( - this, - url("/issues", searchParam), - ".js-SearchForm" - ) - .findByCssSelector("#js-SearchForm-input") - .clearValue() - .click() - .type("") - .type(keys.ENTER) - .sleep(1000) - .getCurrentUrl() - .then(function(currUrl) { - assert.notInclude( - currUrl, - "q=fffffff", - "old search param was removed" - ); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/user-activity-auth.js b/tests/javascript/old/user-activity-auth.js deleted file mode 100644 index 4a3e5fa6b..000000000 --- a/tests/javascript/old/user-activity-auth.js +++ /dev/null @@ -1,112 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "User Activity (auth)", - - setup: function() { - return FunctionalHelpers.login(this); - }, - - teardown: function() { - return FunctionalHelpers.logout(this); - }, - - "We're at the right place": function() { - var username; - return FunctionalHelpers.openPage(this, url("/me"), ".js-username") - .findByCssSelector(".wc-UIContent .wc-Title--l") - .getVisibleText() - .then(function(text) { - var usernameEnd = text.indexOf("'s activity"); - username = text.slice(0, usernameEnd); - }) - .getCurrentUrl() - .then(function(currURL) { - assert.include( - currURL, - username, - "The redirected URL has our username in it." - ); - }) - .end(); - }, - - "IssueListView renders": function() { - return FunctionalHelpers.openPage(this, url("/me"), ".js-list-issue") - .findDisplayedByCssSelector(".js-list-issue") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "IssueList container is visible."); - }) - .end() - .findDisplayedByCssSelector(".js-list-issue .js-IssueList") - .isDisplayed() - .then(function(isDisplayed) { - assert.equal(isDisplayed, true, "IssueList item is visible."); - }) - .end() - .findByCssSelector(".js-IssueList .wc-IssueList-header") - .getVisibleText() - .then(function(text) { - assert.match( - text, - /^Issue\s\d+:\s.+$/, - "Issue should have a non-empty title" - ); - }) - .end() - .findByCssSelector( - ".js-IssueList:nth-child(1) > div:nth-child(1) > p:nth-child(2)" - ) - .getVisibleText() - .then(function(text) { - assert.match( - text, - /comments:\s\d+$/i, - "Issue should display number of comments" - ); - assert.match( - text, - /^Opened:\s\d{4}\-\d{2}\-\d{2}.+/, - "Issue should display creation date" - ); - }) - .end(); - }, - - "Trying to view someone else's activity fails (logged in)": function() { - return FunctionalHelpers.openPage( - this, - url("/activity/someoneelse"), - ".wc-UIContent" - ) - .findByCssSelector(".wc-UIContent .wc-Title--l") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "Forbidden", - "Get a 403 when trying to view someone else's activity" - ); - }) - .end(); - } - }); - } -); diff --git a/tests/javascript/old/user-activity-non-auth.js b/tests/javascript/old/user-activity-non-auth.js deleted file mode 100644 index 96eeb0e7a..000000000 --- a/tests/javascript/old/user-activity-non-auth.js +++ /dev/null @@ -1,40 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -define( - [ - "intern", - "intern!object", - "intern/chai!assert", - "require", - "tests/functional/lib/helpers" - ], - function(intern, registerSuite, assert, require, FunctionalHelpers) { - "use strict"; - var url = function(path) { - return intern.config.siteRoot + path; - }; - - registerSuite({ - name: "User Activity (non-auth)", - - "Trying to view someone else's activity fails (logged out)": function() { - return FunctionalHelpers.openPage( - this, - url("/activity/someoneelse"), - ".wc-UIContent" - ) - .findByCssSelector(".wc-UIContent .wc-Title--l") - .getVisibleText() - .then(function(text) { - assert.include( - text, - "Unauthorized. Please log in", - "User is told to log in." - ); - }); - } - }); - } -); diff --git a/tests/python/__init__.py b/tests/unit/__init__.py similarity index 100% rename from tests/python/__init__.py rename to tests/unit/__init__.py diff --git a/tests/python/test_api_urls.py b/tests/unit/test_api_urls.py similarity index 100% rename from tests/python/test_api_urls.py rename to tests/unit/test_api_urls.py diff --git a/tests/python/test_dashboard.py b/tests/unit/test_dashboard.py similarity index 100% rename from tests/python/test_dashboard.py rename to tests/unit/test_dashboard.py diff --git a/tests/python/test_form.py b/tests/unit/test_form.py similarity index 100% rename from tests/python/test_form.py rename to tests/unit/test_form.py diff --git a/tests/python/test_helpers.py b/tests/unit/test_helpers.py similarity index 100% rename from tests/python/test_helpers.py rename to tests/unit/test_helpers.py diff --git a/tests/python/test_http_caching.py b/tests/unit/test_http_caching.py similarity index 100% rename from tests/python/test_http_caching.py rename to tests/unit/test_http_caching.py diff --git a/tests/python/test_rendering.py b/tests/unit/test_rendering.py similarity index 100% rename from tests/python/test_rendering.py rename to tests/unit/test_rendering.py diff --git a/tests/python/test_topsites.py b/tests/unit/test_topsites.py similarity index 100% rename from tests/python/test_topsites.py rename to tests/unit/test_topsites.py diff --git a/tests/python/test_uploads.py b/tests/unit/test_uploads.py similarity index 100% rename from tests/python/test_uploads.py rename to tests/unit/test_uploads.py diff --git a/tests/python/test_urls.py b/tests/unit/test_urls.py similarity index 100% rename from tests/python/test_urls.py rename to tests/unit/test_urls.py diff --git a/tests/python/test_webhook.py b/tests/unit/test_webhook.py similarity index 100% rename from tests/python/test_webhook.py rename to tests/unit/test_webhook.py From 3d8d9eea6f84a9f733b96a33015f7ae02ce723f2 Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Sat, 13 Jan 2018 12:50:39 -0200 Subject: [PATCH 3/4] Fixes #1986 - Updates travis config --- .travis.yml | 2 +- tests/functional/_intern.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 179bc7d27..ae0b90c5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,4 +53,4 @@ before_script: # now run the tests! script: - nosetests - - node_modules/.bin/intern-runner config=tests/intern reporters=Console + - node ./tests/functional/_intern.js reporters="runner" diff --git a/tests/functional/_intern.js b/tests/functional/_intern.js index a304ff912..8215ffb53 100644 --- a/tests/functional/_intern.js +++ b/tests/functional/_intern.js @@ -56,7 +56,7 @@ intern.configure({ environments: environments, filterErrorStack: true, - reporters: ["pretty"], + reporters: [args.reporters ? args.reporters : "pretty"], functionalSuites: ["./tests/functional/*.js"] }); From d27829bf61150d0ae7e225240d72baca1758ac0e Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Sat, 13 Jan 2018 12:56:40 -0200 Subject: [PATCH 4/4] Fixes #1986 - Change Firefox and Chrome addons in Tarvis to latest stable --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ae0b90c5c..acd2f5088 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,8 @@ branches: language: python addons: - firefox: 55.0 + firefox: latest + chrome: stable python: - "2.7"