From cf87458ba334bada733cd0e104f57e548d1df460 Mon Sep 17 00:00:00 2001 From: Chris Breiding Date: Fri, 12 Jun 2020 14:42:57 -0400 Subject: [PATCH] Fix issue where click hangs if subject has a shadow root and shadow dom support is not enabled (#7692) --- cli/schema/cypress.schema.json | 2 +- cli/types/cypress.d.ts | 6 +++--- cli/types/tests/cypress-tests.ts | 4 ++-- .../integration/commands/actions/click_spec.js | 17 +++++++++++++---- packages/driver/src/dom/elements.ts | 6 ++++-- packages/server/lib/experiments.ts | 2 +- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cli/schema/cypress.schema.json b/cli/schema/cypress.schema.json index 3e4a70a75b..c0906227a5 100644 --- a/cli/schema/cypress.schema.json +++ b/cli/schema/cypress.schema.json @@ -237,7 +237,7 @@ "experimentalShadowDomSupport": { "type": "boolean", "default": false, - "description": "Enables shadow DOM support. Adds the `cy.shadow()` command and the `ignoreShadowBoundaries` option to some DOM commands." + "description": "Enables shadow DOM support. Adds the `cy.shadow()` command and the `includeShadowDom` option to some DOM commands." } } } diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 0543ce4701..f8bd875aee 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -2175,11 +2175,11 @@ declare namespace Cypress { */ interface Shadow { /** - * Ignore shadow boundary and continue searching + * Include shadow DOM in search * * @default: false */ - ignoreShadowBoundaries: boolean + includeShadowDom: boolean } /** @@ -2456,7 +2456,7 @@ declare namespace Cypress { experimentalSourceRewriting: boolean /** * Enables shadow DOM support. Adds the `cy.shadow()` command and - * the `ignoreShadowBoundaries` option to some DOM commands. + * the `includeShadowDom` option to some DOM commands. */ experimentalShadowDomSupport: boolean } diff --git a/cli/types/tests/cypress-tests.ts b/cli/types/tests/cypress-tests.ts index 78155311b9..ccc8e1cba7 100644 --- a/cli/types/tests/cypress-tests.ts +++ b/cli/types/tests/cypress-tests.ts @@ -524,9 +524,9 @@ namespace CypressShadowTests { .find('.bar') .click() - cy.get('.foo', { ignoreShadowBoundaries: true }).click() + cy.get('.foo', { includeShadowDom: true }).click() cy .get('.foo') - .find('.bar', {ignoreShadowBoundaries: true}) + .find('.bar', {includeShadowDom: true}) } diff --git a/packages/driver/cypress/integration/commands/actions/click_spec.js b/packages/driver/cypress/integration/commands/actions/click_spec.js index 610f703d89..93ff851c27 100644 --- a/packages/driver/cypress/integration/commands/actions/click_spec.js +++ b/packages/driver/cypress/integration/commands/actions/click_spec.js @@ -3666,12 +3666,12 @@ describe('src/cy/commands/actions/click', () => { }) }) -describe('composed events', () => { +describe('shadow dom', () => { beforeEach(() => { cy.visit('/fixtures/shadow-dom.html') }) - it('should compose click events', (done) => { + it('composes click events', (done) => { const el = cy.$$('#shadow-element-3')[0].shadowRoot.querySelector('p') cy.$$('#parent-of-shadow-container-0').on('click', () => { @@ -3683,7 +3683,7 @@ describe('composed events', () => { .click() }) - it('should compose dblclick events', (done) => { + it('composes dblclick events', (done) => { const el = cy.$$('#shadow-element-3')[0].shadowRoot.querySelector('p') cy.$$('#parent-of-shadow-container-0').on('dblclick', () => { @@ -3695,7 +3695,7 @@ describe('composed events', () => { .dblclick() }) - it('should compose right click events', (done) => { + it('composes right click events', (done) => { const el = cy.$$('#shadow-element-3')[0].shadowRoot.querySelector('p') cy.$$('#parent-of-shadow-container-0').on('contextmenu', () => { @@ -3706,6 +3706,15 @@ describe('composed events', () => { .get(el) .rightclick() }) + + // https://github.com/cypress-io/cypress/issues/7679 + it('does not hang when experimentalShadowDomSupport is false and clicking on custom element', () => { + Cypress.config('experimentalShadowDomSupport', false) + // needs some size or it's considered invisible and click will fail its prerequisites + cy.$$('#shadow-element-1').css({ padding: 2 }) + + cy.get('#shadow-element-1').click() + }) }) describe('mouse state', () => { diff --git a/packages/driver/src/dom/elements.ts b/packages/driver/src/dom/elements.ts index b8e29f802d..98522bdbfc 100644 --- a/packages/driver/src/dom/elements.ts +++ b/packages/driver/src/dom/elements.ts @@ -1220,8 +1220,10 @@ const elementFromPoint = (doc, x, y) => { // if the node has a shadow root, we must behave like // the browser and find the inner element of the shadow // root at that same point. - while (node?.shadowRoot) { - node = node.shadowRoot.elementFromPoint(x, y) + if (Cypress.config('experimentalShadowDomSupport')) { + while (node?.shadowRoot) { + node = node.shadowRoot.elementFromPoint(x, y) + } } // if we never found an inner/deep element, use the diff --git a/packages/server/lib/experiments.ts b/packages/server/lib/experiments.ts index 6ed57a6607..c9a8859beb 100644 --- a/packages/server/lib/experiments.ts +++ b/packages/server/lib/experiments.ts @@ -54,7 +54,7 @@ const _summaries: StringValues = { experimentalComponentTesting: 'Framework-specific component testing, uses `componentFolder` to load component specs', experimentalSourceRewriting: 'Enables AST-based JS/HTML rewriting. This may fix issues caused by the existing regex-based JS/HTML replacement algorithm.', experimentalGetCookiesSameSite: 'Adds `sameSite` values to the objects yielded from `cy.setCookie()`, `cy.getCookie()`, and `cy.getCookies()`. This will become the default behavior in Cypress 5.0.', - experimentalShadowDomSupport: 'Enables support for shadow DOM traversal, introduces the `shadow()` command and the `ignoreShadowBoundaries` option to traversal commands.', + experimentalShadowDomSupport: 'Enables support for shadow DOM traversal, introduces the `shadow()` command and the `includeShadowDom` option to traversal commands.', } /**