From 576c49d63af93cfd7f917d84d56b9c67fb5d213c Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 6 Jun 2019 12:54:24 -0400 Subject: [PATCH 01/16] add chrome policy check that is logged to stdout/displayed in GUI --- packages/server/lib/errors.coffee | 10 ++ packages/server/lib/gui/events.coffee | 3 + packages/server/lib/modes/run.coffee | 9 +- .../server/lib/util/chrome_policy_check.js | 110 ++++++++++++++++++ packages/server/package.json | 3 + .../test/unit/chrome_policy_check.coffee | 64 ++++++++++ 6 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 packages/server/lib/util/chrome_policy_check.js create mode 100644 packages/server/test/unit/chrome_policy_check.coffee diff --git a/packages/server/lib/errors.coffee b/packages/server/lib/errors.coffee index a125bfac5408..18e9a364f93a 100644 --- a/packages/server/lib/errors.coffee +++ b/packages/server/lib/errors.coffee @@ -781,6 +781,16 @@ getMsgByType = (type, arg1 = {}, arg2) -> Provide a path to an existing fixture file. """ + when "BAD_POLICY_WARNING" + """ + Cypress detected policy settings on your computer that may cause issues. + + The following policies were detected that may prevent Cypress from automating Chrome: + + > #{arg1.join('\n > ')} + + For more information, see https://on.cypress.io/error-messages#extension-policy-settings + """ get = (type, arg1, arg2) -> msg = getMsgByType(type, arg1, arg2) diff --git a/packages/server/lib/gui/events.coffee b/packages/server/lib/gui/events.coffee index 6e51d66e2bfe..109d94fc3003 100644 --- a/packages/server/lib/gui/events.coffee +++ b/packages/server/lib/gui/events.coffee @@ -14,6 +14,7 @@ Updater = require("../updater") Project = require("../project") openProject = require("../open_project") ensureUrl = require("../util/ensure-url") +chromePolicyCheck = require("../util/chrome_policy_check") browsers = require("../browsers") konfig = require("../konfig") @@ -200,6 +201,8 @@ handleEvent = (options, bus, event, id, type, arg) -> onWarning = (warning) -> bus.emit("project:warning", errors.clone(warning, {html: true})) + chromePolicyCheck.run(onWarning) + browsers.getAllBrowsersWith(options.browser) .then (browsers = []) -> options.config = _.assign(options.config, { browsers }) diff --git a/packages/server/lib/modes/run.coffee b/packages/server/lib/modes/run.coffee index 9b6d8321b9b6..ecfde22e2a91 100644 --- a/packages/server/lib/modes/run.coffee +++ b/packages/server/lib/modes/run.coffee @@ -25,6 +25,7 @@ terminal = require("../util/terminal") specsUtil = require("../util/specs") humanTime = require("../util/human_time") electronApp = require("../util/electron_app") +chromePolicyCheck = require("../util/chrome_policy_check") color = (val, c) -> chalk[c](val) @@ -341,6 +342,8 @@ writeOutput = (outputPath, results) -> fs.outputJsonAsync(outputPath, results) +onWarning = _.partialRight(errors.log, 'magenta') + openProjectCreate = (projectRoot, socketId, options) -> ## now open the project to boot the server ## putting our web client app in headless mode @@ -351,8 +354,7 @@ openProjectCreate = (projectRoot, socketId, options) -> morgan: false report: true isTextTerminal: options.isTextTerminal - onWarning: (err) -> - console.log(err.message) + onWarning onError: (err) -> console.log("") if err.details @@ -953,6 +955,9 @@ module.exports = { if not specs.length errors.throw('NO_SPECS_FOUND', config.integrationFolder, specPattern) + if browser.family == 'chrome' + chromePolicyCheck.run(onWarning) + runAllSpecs = ({ beforeSpecRun, afterSpecRun, runUrl }, parallelOverride = parallel) => @runSpecs({ beforeSpecRun diff --git a/packages/server/lib/util/chrome_policy_check.js b/packages/server/lib/util/chrome_policy_check.js new file mode 100644 index 000000000000..7300858397a1 --- /dev/null +++ b/packages/server/lib/util/chrome_policy_check.js @@ -0,0 +1,110 @@ +const _ = require('lodash') +const debug = require('debug')('cypress:server:chrome_policy_check') +const errors = require('../errors') +const os = require('os') + +// https://www.chromium.org/administrators/policy-list-3#Proxy +// https://www.chromium.org/administrators/policy-list-3#ProxySettings +const BAD_PROXY_POLICY_NAMES = [ + 'ProxySettings', + 'ProxyMode', + 'ProxyServerMode', + 'ProxyServer', + 'ProxyPacUrl', + 'ProxyBypassList', +] + +// https://www.chromium.org/administrators/policy-list-3#Extensions +const BAD_EXTENSION_POLICY_NAMES = [ + 'ExtensionInstallBlacklist', + 'ExtensionInstallWhitelist', + 'ExtensionInstallForcelist', + 'ExtensionInstallSources', + 'ExtensionAllowedTypes', + 'ExtensionAllowInsecureUpdates', + 'ExtensionSettings', + 'UninstallBlacklistedExtensions', +] + +const POLICY_KEYS = [ + 'Software\\Policies\\Google\\Chrome', + 'Software\\Policies\\Google\\Chromium', +] + +const POLICY_HKEYS = [ + 'HKEY_LOCAL_MACHINE', + 'HKEY_CURRENT_USER', +] + +function warnIfPolicyMatches (policyNames, allPolicies, warningName, cb) { + const matchedPolicyPaths = _.chain(policyNames) + .map((policyName) => { + return _.chain(allPolicies) + .find({ name: policyName }) + .get('fullPath') + .value() + }) + .filter() + .value() + + if (!matchedPolicyPaths.length) { + return + } + + cb(errors.get(warningName, matchedPolicyPaths)) +} + +function getRunner ({ enumerateValues }) { + function getAllPolicies () { + return _.flattenDeep( + POLICY_KEYS.map((key) => { + return POLICY_HKEYS.map((hkey) => { + return enumerateValues(hkey, key) + .map((value) => { + value.fullPath = `${hkey}\\${key}\\${value.name}` + + return value + }) + }) + }) + ) + } + + return function run (cb) { + try { + debug('running chrome policy check') + + const policies = getAllPolicies() + const badPolicyNames = _.concat(BAD_PROXY_POLICY_NAMES, BAD_EXTENSION_POLICY_NAMES) + + debug('received policies %o', { policies, badPolicyNames }) + + warnIfPolicyMatches(badPolicyNames, policies, 'BAD_POLICY_WARNING', cb) + } catch (err) { + debug('error running policy check %o', { err }) + } + } +} + +module.exports = { + run: _.noop, + getRunner, +} + +/** + * Only check on Windows. While it is possible for macOS/Linux to have preferences set that + * override Cypress's settings, it's never been reported as an issue and would require more + * native extensions to support checking. + */ +if (os.platform() === 'win32') { + try { + const registryJs = require('@cypress/registry-js') + + module.exports = { + run: getRunner(registryJs), + getRunner, + } + } catch (err) { + debug('error initializing chrome policy check %o', { err }) + } +} diff --git a/packages/server/package.json b/packages/server/package.json index f5feadcb5bc5..d6c223eb92b6 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -193,5 +193,8 @@ "uuid": "3.3.2", "widest-line": "3.1.0", "winston": "0.9.0" + }, + "optionalDependencies": { + "@cypress/registry-js": "1.3.3-patch1" } } diff --git a/packages/server/test/unit/chrome_policy_check.coffee b/packages/server/test/unit/chrome_policy_check.coffee new file mode 100644 index 000000000000..30e31a3c9c05 --- /dev/null +++ b/packages/server/test/unit/chrome_policy_check.coffee @@ -0,0 +1,64 @@ +require("../spec_helper") + +_ = require("lodash") +{ stripIndent } = require("common-tags") +chromePolicyCheck = require("#{root}lib/util/chrome_policy_check") + +describe "lib/util/chrome_policy_check", -> + context ".getRunner returns a function", -> + it "calls callback with an error if policies are found", -> + run = chromePolicyCheck.getRunner({ + enumerateValues: (hkey, key) -> + ## mock a registry with a couple of policies + _.get({ + 'HKEY_LOCAL_MACHINE': { + 'Software\\Policies\\Google\\Chrome': [ + { name: 'ProxyServer' } + ] + }, + 'HKEY_CURRENT_USER': { + 'Software\\Policies\\Google\\Chromium': [ + { name: 'ExtensionSettings' } + ] + }, + }, "#{hkey}.#{key}", []) + }) + + cb = sinon.stub() + + run(cb) + + expect(cb).to.be.calledOnce + expect(cb.getCall(0).args[0].message).to.eq(stripIndent """ + Cypress detected policy settings on your computer that may cause issues. + + The following policies were detected that may prevent Cypress from automating Chrome: + + > HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\ProxyServer + > HKEY_CURRENT_USER\\Software\\Policies\\Google\\Chromium\\ExtensionSettings + + For more information, see https://on.cypress.io/error-messages#extension-policy-settings + """ + ) + + it "does not call callback if no policies are found", -> + run = chromePolicyCheck.getRunner({ + enumerateValues: _.constant([]) + }) + + cb = sinon.stub() + + run(cb) + + expect(cb).to.not.be.called + + it "fails silently if enumerateValues throws", -> + run = chromePolicyCheck.getRunner({ + enumerateValues: -> throw new Error('blah') + }) + + cb = sinon.stub() + + run(cb) + + expect(cb).to.not.be.called From 11018906a202ffd63649f0b1592759c707493b40 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 6 Jun 2019 13:35:26 -0400 Subject: [PATCH 02/16] improve warning message --- packages/server/lib/errors.coffee | 2 +- packages/server/lib/modes/run.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/lib/errors.coffee b/packages/server/lib/errors.coffee index 18e9a364f93a..12ae77c3ce4b 100644 --- a/packages/server/lib/errors.coffee +++ b/packages/server/lib/errors.coffee @@ -789,7 +789,7 @@ getMsgByType = (type, arg1 = {}, arg2) -> > #{arg1.join('\n > ')} - For more information, see https://on.cypress.io/error-messages#extension-policy-settings + For more information, see https://on.cypress.io/error-messages#bad-policy-settings """ get = (type, arg1, arg2) -> diff --git a/packages/server/lib/modes/run.coffee b/packages/server/lib/modes/run.coffee index ecfde22e2a91..64522bff35c8 100644 --- a/packages/server/lib/modes/run.coffee +++ b/packages/server/lib/modes/run.coffee @@ -342,7 +342,7 @@ writeOutput = (outputPath, results) -> fs.outputJsonAsync(outputPath, results) -onWarning = _.partialRight(errors.log, 'magenta') +onWarning = _.partialRight(errors.log, 'yellow') openProjectCreate = (projectRoot, socketId, options) -> ## now open the project to boot the server From 07f748fea24e0a12aeaeecedc06ceac00fff4260 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 6 Jun 2019 13:48:27 -0400 Subject: [PATCH 03/16] add desktop-gui warning when launching browser --- .../integration/project_nav_spec.coffee | 22 +++++++++++++++++++ packages/desktop-gui/src/app/nav.scss | 6 +++++ packages/desktop-gui/src/lib/browser-model.js | 2 ++ .../desktop-gui/src/project-nav/browsers.jsx | 17 ++++++++++++++ packages/server/lib/gui/events.coffee | 9 ++++++-- 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee index 790e9b969e90..a069f4cd1676 100644 --- a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee @@ -232,6 +232,28 @@ describe "Project Nav", -> cy.get(".browsers-list") .find(".dropdown-toggle").should("not.be.visible") + describe "browser has a warning attached", -> + beforeEach -> + @browsers = [{ + "name": "chromium", + "displayName": "Chromium", + "family": "chrome", + "version": "49.0.2609.0", + "path": "/Users/bmann/Downloads/chrome-mac/Chromium.app/Contents/MacOS/Chromium", + "majorVersion": "49", + "warnBadPolicy": true + }] + + @config.browsers = @browsers + @openProject.resolve(@config) + + it "shows warning icon with tooltip", -> + cy.get(".browsers .fa-exclamation-triangle") + .then ($el) -> + $el[0].dispatchEvent(new Event("mouseover", {bubbles: true})) + cy.get(".cy-tooltip") + .should("contain", "Cypress detected policy settings on your system that may interfere with using this browser.") + describe "custom browser available", -> beforeEach -> @config.browsers.push({ diff --git a/packages/desktop-gui/src/app/nav.scss b/packages/desktop-gui/src/app/nav.scss index 9cb1e7f2aef0..c06b434164b5 100644 --- a/packages/desktop-gui/src/app/nav.scss +++ b/packages/desktop-gui/src/app/nav.scss @@ -135,6 +135,12 @@ margin-right: 4px; } +.nav .browser-warning { + color: $red-primary; + margin-left: 6px; + margin-right: 4px; +} + .browser-info-tooltip { background: #ececec; border-color: #c7c7c7; diff --git a/packages/desktop-gui/src/lib/browser-model.js b/packages/desktop-gui/src/lib/browser-model.js index d885d0136eb6..80be280abb7a 100644 --- a/packages/desktop-gui/src/lib/browser-model.js +++ b/packages/desktop-gui/src/lib/browser-model.js @@ -9,6 +9,7 @@ export default class Browser { @observable majorVersion @observable info @observable custom + @observable warnBadPolicy @observable isChosen = false constructor (browser) { @@ -20,6 +21,7 @@ export default class Browser { this.majorVersion = browser.majorVersion this.info = browser.info this.custom = browser.custom + this.warnBadPolicy = browser.warnBadPolicy } @computed get icon () { diff --git a/packages/desktop-gui/src/project-nav/browsers.jsx b/packages/desktop-gui/src/project-nav/browsers.jsx index 141eada6336c..663f4d8b2981 100644 --- a/packages/desktop-gui/src/project-nav/browsers.jsx +++ b/packages/desktop-gui/src/project-nav/browsers.jsx @@ -73,11 +73,28 @@ export default class Browsers extends Component { {prefixText}{' '} {browser.displayName}{' '} {browser.majorVersion} + {this._warnBadPolicy(browser)} {this._info(browser)} ) } + _warnBadPolicy (browser) { + if (!browser.warnBadPolicy) return null + + return ( + + + + + + ) + } + _info (browser) { if (!browser.info) return null diff --git a/packages/server/lib/gui/events.coffee b/packages/server/lib/gui/events.coffee index 109d94fc3003..1d52c243012d 100644 --- a/packages/server/lib/gui/events.coffee +++ b/packages/server/lib/gui/events.coffee @@ -201,12 +201,17 @@ handleEvent = (options, bus, event, id, type, arg) -> onWarning = (warning) -> bus.emit("project:warning", errors.clone(warning, {html: true})) - chromePolicyCheck.run(onWarning) - browsers.getAllBrowsersWith(options.browser) .then (browsers = []) -> options.config = _.assign(options.config, { browsers }) .then -> + chromePolicyCheck.run (err) -> + options.config.browsers.forEach (browser) -> + if browser.family == 'chrome' + browser.warnBadPolicy = true + + onWarning(err) + openProject.create(arg, options, { onFocusTests: onFocusTests onSpecChanged: onSpecChanged From 994fd7b4fc758182ba494c16d5826b8aca9ac259 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 6 Jun 2019 14:55:39 -0400 Subject: [PATCH 04/16] update tests --- .../desktop-gui/cypress/integration/project_nav_spec.coffee | 2 +- packages/server/test/unit/chrome_policy_check.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee index a069f4cd1676..eb19b19981c1 100644 --- a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee @@ -151,7 +151,7 @@ describe "Project Nav", -> it "sends the required parameters to launch a browser", -> browserArg = @ipc.launchBrowser.getCall(0).args[0].browser expect(browserArg).to.have.keys([ - "family", "name", "path", "version", "majorVersion", "displayName", "info", "isChosen", "custom" + "family", "name", "path", "version", "majorVersion", "displayName", "info", "isChosen", "custom", "warnBadPolicy" ]) expect(browserArg.path).to.include('/') expect(browserArg.family).to.equal('chrome') diff --git a/packages/server/test/unit/chrome_policy_check.coffee b/packages/server/test/unit/chrome_policy_check.coffee index 30e31a3c9c05..658f23ed8f35 100644 --- a/packages/server/test/unit/chrome_policy_check.coffee +++ b/packages/server/test/unit/chrome_policy_check.coffee @@ -37,7 +37,7 @@ describe "lib/util/chrome_policy_check", -> > HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\ProxyServer > HKEY_CURRENT_USER\\Software\\Policies\\Google\\Chromium\\ExtensionSettings - For more information, see https://on.cypress.io/error-messages#extension-policy-settings + For more information, see https://on.cypress.io/error-messages#bad-policy-settings """ ) From 971991f2a76e6c0ff6a42b8d82361481705a752a Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Fri, 7 Jun 2019 12:55:39 -0400 Subject: [PATCH 05/16] clean up adding warnings to browsers in the gui --- .../cypress/integration/project_nav_spec.coffee | 6 +++--- packages/desktop-gui/src/lib/browser-model.js | 4 ++-- packages/desktop-gui/src/project-nav/browsers.jsx | 8 ++++---- packages/launcher/lib/types.ts | 2 ++ packages/server/lib/errors.coffee | 4 ++++ packages/server/lib/gui/events.coffee | 2 +- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee index eb19b19981c1..663f890b3e97 100644 --- a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee @@ -151,7 +151,7 @@ describe "Project Nav", -> it "sends the required parameters to launch a browser", -> browserArg = @ipc.launchBrowser.getCall(0).args[0].browser expect(browserArg).to.have.keys([ - "family", "name", "path", "version", "majorVersion", "displayName", "info", "isChosen", "custom", "warnBadPolicy" + "family", "name", "path", "version", "majorVersion", "displayName", "info", "isChosen", "custom", "warning" ]) expect(browserArg.path).to.include('/') expect(browserArg.family).to.equal('chrome') @@ -241,7 +241,7 @@ describe "Project Nav", -> "version": "49.0.2609.0", "path": "/Users/bmann/Downloads/chrome-mac/Chromium.app/Contents/MacOS/Chromium", "majorVersion": "49", - "warnBadPolicy": true + "warning": "Cypress detected policy settings on your computer that may interfere with using this browser." }] @config.browsers = @browsers @@ -252,7 +252,7 @@ describe "Project Nav", -> .then ($el) -> $el[0].dispatchEvent(new Event("mouseover", {bubbles: true})) cy.get(".cy-tooltip") - .should("contain", "Cypress detected policy settings on your system that may interfere with using this browser.") + .should("contain", "Cypress detected policy settings on your computer that may interfere with using this browser.") describe "custom browser available", -> beforeEach -> diff --git a/packages/desktop-gui/src/lib/browser-model.js b/packages/desktop-gui/src/lib/browser-model.js index 80be280abb7a..e830432d3444 100644 --- a/packages/desktop-gui/src/lib/browser-model.js +++ b/packages/desktop-gui/src/lib/browser-model.js @@ -9,7 +9,7 @@ export default class Browser { @observable majorVersion @observable info @observable custom - @observable warnBadPolicy + @observable warning @observable isChosen = false constructor (browser) { @@ -21,7 +21,7 @@ export default class Browser { this.majorVersion = browser.majorVersion this.info = browser.info this.custom = browser.custom - this.warnBadPolicy = browser.warnBadPolicy + this.warning = browser.warning } @computed get icon () { diff --git a/packages/desktop-gui/src/project-nav/browsers.jsx b/packages/desktop-gui/src/project-nav/browsers.jsx index 663f4d8b2981..b3ff4f8229ab 100644 --- a/packages/desktop-gui/src/project-nav/browsers.jsx +++ b/packages/desktop-gui/src/project-nav/browsers.jsx @@ -73,19 +73,19 @@ export default class Browsers extends Component { {prefixText}{' '} {browser.displayName}{' '} {browser.majorVersion} - {this._warnBadPolicy(browser)} + {this._warn(browser)} {this._info(browser)} ) } - _warnBadPolicy (browser) { - if (!browser.warnBadPolicy) return null + _warn (browser) { + if (!browser.warning) return null return ( diff --git a/packages/launcher/lib/types.ts b/packages/launcher/lib/types.ts index 1ba6ca1f1cd4..1aca1ebec540 100644 --- a/packages/launcher/lib/types.ts +++ b/packages/launcher/lib/types.ts @@ -35,6 +35,8 @@ export type FoundBrowser = Browser & { custom?: boolean /** optional info that will be shown in the GUI */ info?: string + /** optional warning that will be shown in the GUI */ + warning?: string } // all common type definition for this module diff --git a/packages/server/lib/errors.coffee b/packages/server/lib/errors.coffee index 12ae77c3ce4b..b88f0900a70c 100644 --- a/packages/server/lib/errors.coffee +++ b/packages/server/lib/errors.coffee @@ -791,6 +791,10 @@ getMsgByType = (type, arg1 = {}, arg2) -> For more information, see https://on.cypress.io/error-messages#bad-policy-settings """ + when "BAD_POLICY_WARNING_TOOLTIP" + """ + Cypress detected policy settings on your computer that may interfere with using this browser. + """ get = (type, arg1, arg2) -> msg = getMsgByType(type, arg1, arg2) diff --git a/packages/server/lib/gui/events.coffee b/packages/server/lib/gui/events.coffee index 1d52c243012d..5321e84f43ba 100644 --- a/packages/server/lib/gui/events.coffee +++ b/packages/server/lib/gui/events.coffee @@ -208,7 +208,7 @@ handleEvent = (options, bus, event, id, type, arg) -> chromePolicyCheck.run (err) -> options.config.browsers.forEach (browser) -> if browser.family == 'chrome' - browser.warnBadPolicy = true + browser.warning = errors.getMsgByType('BAD_POLICY_WARNING_TOOLTIP') onWarning(err) From 28a8eda278185b55921cb69fb3338bcee9228d5f Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Fri, 7 Jun 2019 14:18:21 -0400 Subject: [PATCH 06/16] support multiple warnings in gui --- .../integration/warning_message_spec.coffee | 38 +++++++++++++++++++ .../desktop-gui/src/project/project-model.js | 19 ++++++---- packages/desktop-gui/src/project/project.jsx | 18 +++++---- .../desktop-gui/src/projects/projects-api.js | 2 +- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/warning_message_spec.coffee b/packages/desktop-gui/cypress/integration/warning_message_spec.coffee index afbc4f3f767d..9cd1d1be6a56 100644 --- a/packages/desktop-gui/cypress/integration/warning_message_spec.coffee +++ b/packages/desktop-gui/cypress/integration/warning_message_spec.coffee @@ -80,3 +80,41 @@ describe "WarningMessage", -> .click() .then -> expect(@ipc.externalOpen).not.to.be.called + + context "with multiple warnings", -> + beforeEach -> + @warningObj2 = {type: "GOOD_BUT_NOT_TOO_GOOD", name: "Fairly good warning", message: "Other message"} + + it "shows multiple warnings", -> + cy.shouldBeOnProjectSpecs().then => + @ipc.onProjectWarning.yield(null, @warningObj) + @ipc.onProjectWarning.yield(null, @warningObj2) + + cy.get(".alert-warning") + .should("have.length", 2) + .should("be.visible") + .first() + .should("contain", "Some warning") + cy.get(".alert-warning") + .its('1') + .should("contain", "Other message") + + it "can dismiss the warnings", -> + cy.shouldBeOnProjectSpecs().then => + @ipc.onProjectWarning.yield(null, @warningObj) + @ipc.onProjectWarning.yield(null, @warningObj2) + + cy.get(".alert-warning") + .should("contain", "Some warning") + .should("contain", "Other message") + .get(".alert-warning button") + .first() + .click() + cy.get(".alert-warning") + .should("not.contain", "Some warning") + .should("contain", "Other message") + .get(".alert-warning button") + .click() + cy.get(".alert-warning") + .should("not.contain", "Some warning") + .should("not.contain", "Other message") diff --git a/packages/desktop-gui/src/project/project-model.js b/packages/desktop-gui/src/project/project-model.js index a499b2b0ff82..aa5a5df7d7e6 100644 --- a/packages/desktop-gui/src/project/project-model.js +++ b/packages/desktop-gui/src/project/project-model.js @@ -53,7 +53,7 @@ export default class Project { @observable browserState = 'closed' @observable resolvedConfig @observable error - @observable warning + @observable warnings = [] @observable apiError @observable parentTestsFolderDisplay @observable integrationExampleName @@ -209,18 +209,23 @@ export default class Project { this.error = null } - @action setWarning (warning) { + @action addWarning (warning) { if (!this.dismissedWarnings[this._serializeWarning(warning)]) { - this.warning = warning + this.warnings.push(warning) } } - @action clearWarning () { - if (this.warning) { - this.dismissedWarnings[this._serializeWarning(this.warning)] = true + @action clearWarning (warning) { + if (!warning) { + // calling with no warning clears all warnings + return this.warnings.map((warning) => { + return this.clearWarning(warning) + }) } - this.warning = null + this.dismissedWarnings[this._serializeWarning(warning)] = true + + this.warnings = _.without(this.warnings, warning) } _serializeWarning (warning) { diff --git a/packages/desktop-gui/src/project/project.jsx b/packages/desktop-gui/src/project/project.jsx index 24b2d8a42ab3..df9a0d2ed482 100644 --- a/packages/desktop-gui/src/project/project.jsx +++ b/packages/desktop-gui/src/project/project.jsx @@ -39,15 +39,11 @@ class Project extends Component { if (this.props.project.error) return - const { warning } = this.props.project - return (
- {warning && - - } + {this._renderWarnings()} {this._currentView()}
@@ -72,8 +68,16 @@ class Project extends Component { } } - _removeWarning = () => { - this.props.project.clearWarning() + _renderWarnings = () => { + const { warnings } = this.props.project + + return warnings.map((warning, i) => + ( this._removeWarning(warning)}/>) + ) + } + + _removeWarning = (warning) => { + this.props.project.clearWarning(warning) } _reopenProject = () => { diff --git a/packages/desktop-gui/src/projects/projects-api.js b/packages/desktop-gui/src/projects/projects-api.js index 78a4d1773af5..32c1ba1bf392 100644 --- a/packages/desktop-gui/src/projects/projects-api.js +++ b/packages/desktop-gui/src/projects/projects-api.js @@ -168,7 +168,7 @@ const openProject = (project) => { }) ipc.onProjectWarning((__, warning) => { - project.setWarning(warning) + project.addWarning(warning) }) return ipc.openProject(project.path) From c46b0f42a43e9d0dd784b3df5f9307d62863cd2e Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Fri, 7 Jun 2019 14:25:58 -0400 Subject: [PATCH 07/16] update on-link --- packages/server/lib/errors.coffee | 2 +- packages/server/test/unit/chrome_policy_check.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/lib/errors.coffee b/packages/server/lib/errors.coffee index b88f0900a70c..565714865f84 100644 --- a/packages/server/lib/errors.coffee +++ b/packages/server/lib/errors.coffee @@ -789,7 +789,7 @@ getMsgByType = (type, arg1 = {}, arg2) -> > #{arg1.join('\n > ')} - For more information, see https://on.cypress.io/error-messages#bad-policy-settings + For more information, see https://on.cypress.io/bad-browser-policy """ when "BAD_POLICY_WARNING_TOOLTIP" """ diff --git a/packages/server/test/unit/chrome_policy_check.coffee b/packages/server/test/unit/chrome_policy_check.coffee index 658f23ed8f35..ee0914517e13 100644 --- a/packages/server/test/unit/chrome_policy_check.coffee +++ b/packages/server/test/unit/chrome_policy_check.coffee @@ -37,7 +37,7 @@ describe "lib/util/chrome_policy_check", -> > HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\ProxyServer > HKEY_CURRENT_USER\\Software\\Policies\\Google\\Chromium\\ExtensionSettings - For more information, see https://on.cypress.io/error-messages#bad-policy-settings + For more information, see https://on.cypress.io/bad-browser-policy """ ) From 9d3f05af9167741dda40a1aa14a3b5feb7fa6f99 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 13 Jun 2019 14:53:17 -0400 Subject: [PATCH 08/16] don't show warning in open mode --- packages/server/lib/gui/events.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/server/lib/gui/events.coffee b/packages/server/lib/gui/events.coffee index 5321e84f43ba..7c5d884bde4c 100644 --- a/packages/server/lib/gui/events.coffee +++ b/packages/server/lib/gui/events.coffee @@ -210,8 +210,6 @@ handleEvent = (options, bus, event, id, type, arg) -> if browser.family == 'chrome' browser.warning = errors.getMsgByType('BAD_POLICY_WARNING_TOOLTIP') - onWarning(err) - openProject.create(arg, options, { onFocusTests: onFocusTests onSpecChanged: onSpecChanged From 813432b09db2b0d16980cd8c827295ac4e9ee16f Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 13 Jun 2019 15:03:13 -0400 Subject: [PATCH 09/16] add test for warning getting attached, add hyperlink to warning tooltip --- packages/server/lib/errors.coffee | 2 +- .../server/test/unit/gui/events_spec.coffee | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/server/lib/errors.coffee b/packages/server/lib/errors.coffee index 565714865f84..7e2a4cc71601 100644 --- a/packages/server/lib/errors.coffee +++ b/packages/server/lib/errors.coffee @@ -793,7 +793,7 @@ getMsgByType = (type, arg1 = {}, arg2) -> """ when "BAD_POLICY_WARNING_TOOLTIP" """ - Cypress detected policy settings on your computer that may interfere with using this browser. + Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy """ get = (type, arg1, arg2) -> diff --git a/packages/server/test/unit/gui/events_spec.coffee b/packages/server/test/unit/gui/events_spec.coffee index eb9f1b70624b..872d4080684c 100644 --- a/packages/server/test/unit/gui/events_spec.coffee +++ b/packages/server/test/unit/gui/events_spec.coffee @@ -5,6 +5,7 @@ EE = require("events") extension = require("@packages/extension") electron = require("electron") Promise = require("bluebird") +chromePolicyCheck = require("#{root}../lib/util/chrome_policy_check") cache = require("#{root}../lib/cache") logger = require("#{root}../lib/logger") Project = require("#{root}../lib/project") @@ -493,6 +494,34 @@ describe "lib/gui/events", -> } ) + it "attaches warning to Chrome browsers when Chrome policy check fails", -> + sinon.stub(openProject, "create").resolves() + @options.browser = "/foo" + + browsers.getAllBrowsersWith.withArgs("/foo").resolves([{family: 'chrome'}, {family: 'some other'}]) + + sinon.stub(chromePolicyCheck, "run").callsArgWith(0, new Error) + + @handleEvent("open:project", "/_test-output/path/to/project").then => + expect(browsers.getAllBrowsersWith).to.be.calledWith(@options.browser) + expect(openProject.create).to.be.calledWithMatch( + "/_test-output/path/to/project", + { + browser: "/foo", + config: { + browsers: [ + { + family: "chrome" + warning: "Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy" + }, + { + family: "some other" + } + ] + } + } + ) + describe "close:project", -> beforeEach -> sinon.stub(Project.prototype, "close").withArgs({sync: true}).resolves() From f868ec619b5e8a83133a5b3d3b6ee68dcfeec490 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 13 Jun 2019 15:19:04 -0400 Subject: [PATCH 10/16] render tooltip warnings with markdown --- .../integration/project_nav_spec.coffee | 10 +++-- .../desktop-gui/src/lib/markdown-renderer.jsx | 37 +++++++++++++++++++ .../desktop-gui/src/project-nav/browsers.jsx | 3 +- .../src/project/warning-message.jsx | 31 ++-------------- 4 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 packages/desktop-gui/src/lib/markdown-renderer.jsx diff --git a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee index 663f890b3e97..9ced00968509 100644 --- a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee @@ -241,18 +241,22 @@ describe "Project Nav", -> "version": "49.0.2609.0", "path": "/Users/bmann/Downloads/chrome-mac/Chromium.app/Contents/MacOS/Chromium", "majorVersion": "49", - "warning": "Cypress detected policy settings on your computer that may interfere with using this browser." + "warning": "Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy" }] @config.browsers = @browsers @openProject.resolve(@config) - it "shows warning icon with tooltip", -> + it "shows warning icon with linkified tooltip", -> cy.get(".browsers .fa-exclamation-triangle") .then ($el) -> $el[0].dispatchEvent(new Event("mouseover", {bubbles: true})) cy.get(".cy-tooltip") - .should("contain", "Cypress detected policy settings on your computer that may interfere with using this browser.") + .should("contain", "Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see") + .get(".cy-tooltip a") + .click() + .then () -> + expect(@ipc.externalOpen).to.be.calledWith("https://on.cypress.io/bad-browser-policy") describe "custom browser available", -> beforeEach -> diff --git a/packages/desktop-gui/src/lib/markdown-renderer.jsx b/packages/desktop-gui/src/lib/markdown-renderer.jsx new file mode 100644 index 000000000000..2cac4f4d548a --- /dev/null +++ b/packages/desktop-gui/src/lib/markdown-renderer.jsx @@ -0,0 +1,37 @@ +import React from 'react' +import Markdown from 'markdown-it' + +import ipc from '../lib/ipc' + +const md = new Markdown({ + html: true, + linkify: true, +}) + +export default class MarkdownRenderer extends React.PureComponent { + componentDidMount () { + this.node.addEventListener('click', this._clickHandler) + } + + componentWillUnmount () { + this.node.removeEventListener('click', this._clickHandler) + } + + _clickHandler (e) { + if (e.target.href) { + e.preventDefault() + + return ipc.externalOpen(e.target.href) + } + } + + render () { + return ( + this.node = node} + dangerouslySetInnerHTML={{ + __html: md.render(this.props.markdown), + }}> + + ) + } +} diff --git a/packages/desktop-gui/src/project-nav/browsers.jsx b/packages/desktop-gui/src/project-nav/browsers.jsx index b3ff4f8229ab..989c0937dd46 100644 --- a/packages/desktop-gui/src/project-nav/browsers.jsx +++ b/packages/desktop-gui/src/project-nav/browsers.jsx @@ -2,6 +2,7 @@ import React, { Component } from 'react' import { observer } from 'mobx-react' import Tooltip from '@cypress/react-tooltip' import Dropdown from '../dropdown/dropdown' +import MarkdownRenderer from '../lib/markdown-renderer' import projectsApi from '../projects/projects-api' @@ -85,7 +86,7 @@ export default class Browsers extends Component { return ( } placement='bottom' className='browser-info-tooltip cy-tooltip' > diff --git a/packages/desktop-gui/src/project/warning-message.jsx b/packages/desktop-gui/src/project/warning-message.jsx index 1e3197878176..9acc559bb5ae 100644 --- a/packages/desktop-gui/src/project/warning-message.jsx +++ b/packages/desktop-gui/src/project/warning-message.jsx @@ -1,32 +1,9 @@ import React, { Component } from 'react' import { observer } from 'mobx-react' -import Markdown from 'markdown-it' - -import ipc from '../lib/ipc' - -const md = new Markdown({ - html: true, - linkify: true, -}) +import MarkdownRenderer from '../lib/markdown-renderer' @observer class WarningMessage extends Component { - componentDidMount () { - this.warningMessageNode.addEventListener('click', this._clickHandler) - } - - componentWillUnmount () { - this.warningMessageNode.removeEventListener('click', this._clickHandler) - } - - _clickHandler (e) { - if (e.target.href) { - e.preventDefault() - - return ipc.externalOpen(e.target.href) - } - } - render () { const warningText = this.props.warning.message.split('\n').join('
') @@ -36,9 +13,9 @@ class WarningMessage extends Component { {' '} Warning

-
this.warningMessageNode = node} dangerouslySetInnerHTML={{ - __html: md.render(warningText), - }}>
+
+ +
From 91ab468cd14a550a3d2305143d107a34323b897a Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Tue, 18 Jun 2019 12:02:28 -0400 Subject: [PATCH 11/16] pass NO_CHECK_DEPS=1 to skip dep check --- scripts/check-deps.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/check-deps.js b/scripts/check-deps.js index 77b89a2bc74c..2b4d3184e867 100644 --- a/scripts/check-deps.js +++ b/scripts/check-deps.js @@ -6,6 +6,10 @@ const fs = require('fs') const path = require('path') const stripAnsi = require('strip-ansi') +if (process.env.NO_CHECK_DEPS) { + process.exit(0) +} + const args = require('minimist')(process.argv.slice(2)) const cwd = args.cwd || process.cwd() From a10308b2c474a2bc233f641414a67f3736ddcc6e Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 20 Jun 2019 11:20:31 -0400 Subject: [PATCH 12/16] @cypress/react-tooltip@0.5.0 - adds clickability to tooltips --- packages/desktop-gui/package.json | 2 +- packages/reporter/package.json | 2 +- packages/runner/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/desktop-gui/package.json b/packages/desktop-gui/package.json index a71010033e23..64ac3c0c2ae5 100644 --- a/packages/desktop-gui/package.json +++ b/packages/desktop-gui/package.json @@ -27,7 +27,7 @@ "@babel/plugin-proposal-object-rest-spread": "7.4.4", "@cypress/icons": "0.7.0", "@cypress/json-schemas": "5.31.3", - "@cypress/react-tooltip": "0.4.0", + "@cypress/react-tooltip": "0.5.0", "bin-up": "1.2.0", "bluebird": "3.5.3", "bootstrap-sass": "3.4.1", diff --git a/packages/reporter/package.json b/packages/reporter/package.json index a605cdb0b695..180cd3b08855 100644 --- a/packages/reporter/package.json +++ b/packages/reporter/package.json @@ -28,7 +28,7 @@ ], "devDependencies": { "@babel/plugin-proposal-object-rest-spread": "7.4.4", - "@cypress/react-tooltip": "0.4.0", + "@cypress/react-tooltip": "0.5.0", "bin-up": "1.2.0", "chai": "3.5.0", "chai-enzyme": "1.0.0-beta.1", diff --git a/packages/runner/package.json b/packages/runner/package.json index 4e4dc79d2b85..aa1f398b66f8 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -25,7 +25,7 @@ ], "devDependencies": { "@babel/plugin-proposal-object-rest-spread": "7.4.4", - "@cypress/react-tooltip": "0.4.0", + "@cypress/react-tooltip": "0.5.0", "bin-up": "1.2.0", "bluebird": "3.5.0", "chai": "4.2.0", From 8eda151f058082760d81cfd396c8a45018218574 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 20 Jun 2019 11:26:27 -0400 Subject: [PATCH 13/16] add link to issue --- packages/server/lib/util/chrome_policy_check.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/server/lib/util/chrome_policy_check.js b/packages/server/lib/util/chrome_policy_check.js index 7300858397a1..8e550f7aec6d 100644 --- a/packages/server/lib/util/chrome_policy_check.js +++ b/packages/server/lib/util/chrome_policy_check.js @@ -95,6 +95,7 @@ module.exports = { * Only check on Windows. While it is possible for macOS/Linux to have preferences set that * override Cypress's settings, it's never been reported as an issue and would require more * native extensions to support checking. + * https://github.com/cypress-io/cypress/issues/4391 */ if (os.platform() === 'win32') { try { From f5939685b74b64d53b25a1558c9724e36e037dc7 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 20 Jun 2019 11:36:18 -0400 Subject: [PATCH 14/16] dont need to update reporter and runner --- packages/reporter/package.json | 2 +- packages/runner/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/reporter/package.json b/packages/reporter/package.json index 180cd3b08855..a605cdb0b695 100644 --- a/packages/reporter/package.json +++ b/packages/reporter/package.json @@ -28,7 +28,7 @@ ], "devDependencies": { "@babel/plugin-proposal-object-rest-spread": "7.4.4", - "@cypress/react-tooltip": "0.5.0", + "@cypress/react-tooltip": "0.4.0", "bin-up": "1.2.0", "chai": "3.5.0", "chai-enzyme": "1.0.0-beta.1", diff --git a/packages/runner/package.json b/packages/runner/package.json index aa1f398b66f8..4e4dc79d2b85 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -25,7 +25,7 @@ ], "devDependencies": { "@babel/plugin-proposal-object-rest-spread": "7.4.4", - "@cypress/react-tooltip": "0.5.0", + "@cypress/react-tooltip": "0.4.0", "bin-up": "1.2.0", "bluebird": "3.5.0", "chai": "4.2.0", From 9945a3e9e82c3d779a6220cccb7bc2b514ba3538 Mon Sep 17 00:00:00 2001 From: Brian Mann Date: Wed, 3 Jul 2019 14:32:19 +0200 Subject: [PATCH 15/16] use synchronous console.log, not async errors.log for displaying yellow warnings --- packages/server/lib/modes/run.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/server/lib/modes/run.coffee b/packages/server/lib/modes/run.coffee index d216192ed80c..cbf894dfc172 100644 --- a/packages/server/lib/modes/run.coffee +++ b/packages/server/lib/modes/run.coffee @@ -342,7 +342,8 @@ writeOutput = (outputPath, results) -> fs.outputJsonAsync(outputPath, results) -onWarning = _.partialRight(errors.log, 'yellow') +onWarning = (err) -> + console.log(chalk.yellow(err.message)) openProjectCreate = (projectRoot, socketId, options) -> ## now open the project to boot the server From 03d8a0c85c9cd62defe6ae023adf749d95d28b67 Mon Sep 17 00:00:00 2001 From: Brian Mann Date: Wed, 3 Jul 2019 14:36:24 +0200 Subject: [PATCH 16/16] use trigger, do not build up events manually /cc @flotwig --- .../cypress/integration/project_nav_spec.coffee | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee index 9ced00968509..52fafe589002 100644 --- a/packages/desktop-gui/cypress/integration/project_nav_spec.coffee +++ b/packages/desktop-gui/cypress/integration/project_nav_spec.coffee @@ -248,9 +248,7 @@ describe "Project Nav", -> @openProject.resolve(@config) it "shows warning icon with linkified tooltip", -> - cy.get(".browsers .fa-exclamation-triangle") - .then ($el) -> - $el[0].dispatchEvent(new Event("mouseover", {bubbles: true})) + cy.get(".browsers .fa-exclamation-triangle").trigger("mouseover") cy.get(".cy-tooltip") .should("contain", "Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see") .get(".cy-tooltip a") @@ -300,7 +298,6 @@ describe "Project Nav", -> it "shows info icon with tooltip", -> cy.get(".browsers .fa-info-circle") - .then ($el) -> - $el[0].dispatchEvent(new Event("mouseover", {bubbles: true})) + .trigger("mouseover") cy.get(".cy-tooltip") .should("contain", @info)