-
-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: calculate positions for elements inside iframes correctly #29
fix: calculate positions for elements inside iframes correctly #29
Conversation
src/getCypressElementCoordinates.ts
Outdated
} | ||
|
||
return { | ||
x: finalX, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also it is required to calculate the real size of the iframe (if it was scaled). Just like we are doing already for the upper iframe
I cannot merge PRs without tests. If you want this to be merged please add some tests or wait – I will add some tests myself |
I have an update with tests I'll push up here soon, just gotta polish it up a bit. I don't think my changes cover elements that are being transformed themselves ( |
5d6b028
to
3b71e78
Compare
Just pushed up a commit fixing the failing test and rebasing on develop. Sorry about that, I recently changed some git defaults to not index untracked files by default. I typically work in a very large repo and that change speeds up all my git commands. Still haven't acclimated to it yet, so I keep forgetting to manually add untracked files to my commits. Let me know what you think of the approach I went with (or take the PR over if you'd prefer), i added some HTML files to test the iframe behavior against. |
I'm still getting a failure on the swipe test, for the toTop test. It only fails when run in CI mode, it passes fine with |
src/getCypressElementCoordinates.ts
Outdated
const iframes = []; | ||
|
||
let currentWindow: Window | null = element.ownerDocument.defaultView; | ||
while (currentWindow && currentWindow.frameElement && currentWindow !== window) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note regarding .frameElement
- it should return null for a cross-origin frame which could be a problem when running with --disable-web-security
but I've checked that and it seems that this flag makes .frameElement
return the correct element from the parent.
src/getCypressElementCoordinates.ts
Outdated
} | ||
|
||
if (currentWindow) { | ||
iframes.unshift(window.parent.document.querySelector('iframe')); // The Cypress app frame |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering - couldn't this algorithm be simplified to process the whole thing in a single pass when traversing elements up? This potentially would also allow dropping this Cypress-specific~ line.
Hey, just checking in here. I haven't had time to come back to this, but I'm hoping to put some more time in this upcoming weekend to see if I can figure out why the build is failing (and to respond to the outstanding comments) |
* feat: add option changing scrolling behavior (#30) * feat: allow changing scrolling behavior for realClick and realHover * feat: Fallback to Cypress.config('scrollBehavior') * feat: Add specs for scrollBehavior to click and hover * fix: ignore TS errors or Cypress <6.1.0 * fix: remove false option for scrollBehavior * fix: bump dev dependency for cypress to 6.1 for compilation error * [] Move scrollBehavior specs directly into click.spec and hover.spec * [] Fix failing swipe tests by passing scrollBehavior * Reduce renames * Remove unused option Co-authored-by: Dmitriy Kovalenko <[email protected]> * Add support for radius options in realTouch (#31) * test: add test for radius options in realTouch (#32) * fix(realTouch): accept 0 for position x/y values (#33) * feat: Transpile files to cjs (#34) * fix: calculate positions for elements inside iframes correctly (#29) * fix: calculate positions for elements inside iframes correctly * Handle iframes with scale transforms * [] Refactor getCypressElementCoordinates to better handle scaled frames * [] Add tests for click and hover in iframes * [] Add HTML files to fixtures folder * Remove unnecessary @ts-expect-error * Change logic of get cypress element * Make swipe tests retryable Co-authored-by: Dmitriy Kovalenko <[email protected]> * Fix touch radius test Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]>
🎉 This PR is included in version 1.3.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
// for cross origin domains .frameElement returns null so query using parentWindow | ||
// but when running using --disable-web-security it will return the frame element | ||
(currentWindow.frameElement as HTMLElement) ?? | ||
currentWindow.parent.document.querySelector("iframe") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of curiosity - is there any situation in which this fallback would actually kick in? note that if it does it might not return the correct iframe as there might be multiple iframes on the page and this doesn't account for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep when running with disable-web-security it follows the original .frameElement.
I didn’t get the last part. This prop returns the frame where window is embedded. It means that it returns the upper frame which is the only that contains this window.
If think this way it may be really possible to remove this branching, but what exact problem do you see here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep when running with disable-web-security it follows the original .frameElement.
I was the one who has checked how this behaves with disable-web-security and to my slight surprise, it just has returned the "correct" .frameElement
despite .frameElement
having to return null
for cross-origin iframes. So it is as web-security is also responsible for guarding access to .frameElement
- so it returns null
normally and if we disable it starts to return the correct element.
So using disable-web-security (according to my tests) doesn't influence the logic anyhow - and from what I understand we shouldn't be even able to select cross-origin element in Cypress (when not using disable-web-security) as it's running in the real browser's context so it would just not allow us to do that.
I didn’t get the last part. This prop returns the frame where window is embedded. It means that it returns the upper frame which is the only that contains this window.
I was referring to the fallback logic (currentWindow.parent.document.querySelector("iframe")
) - it can just queries the first iframe but the currentWindow.parent.document
might contain more than one and thus we can select incorrect one using this.
If think this way it may be really possible to remove this branching, but what exact problem do you see here?
I just usually try to avoid dead branches of the code and was really curious if this is dead or not (the ??
part). I might very well just miss something here. And, as mentioned, even if it's not dead I believe that it might lead to incorrect results at times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. So it needs to be processed by looking for iframe which content window is equal to current frame, yeah it looks correct.
Feel free to open PR, I am on vacation right now so won’t code — but I can review PR and merge if everything is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question is - how to write a test for this? Under what circumstances are we able to "fail" reading the currentWindow.frameElement
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case except cypress is running over chrome with disabled web security I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a regular scenario (without disabled web security) - we can't even get access to cross-origin frames. I've just re-tested this using this repo:
Uncaught DOMException: Blocked a frame with origin "https://example.cypress.io" from accessing a cross-origin frame.
So I think (but not entirely sure) that it's not possible to get access to an element from some inner cross-origin so this entire logic just can't be executed on such an element (no cypress command can).
However, I see that a regular relation between embedding context and an embedded iframe is somehow hacked for the AUT in Cypress. How do you even achieve that? 🤔 I have never actually thought about it as our tests are running against localhost.
And note - a cross-origin AUT has .frameElement === null
. So this logic is actually not dead 👍 As it handles the last iframe on the stack (the AUT) and it just happens that the AUT is the first one (at least for now 😉 ).
If I have made any mistake in my whole reasoning - please let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cypress proxies response of your website for testing so the origin will always be the same. The whole cypress is build over making iframe same origin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, that's good to know! Now when you have said that I think I've seen your injection code when debugging - just didn't connect the dots.
Either way - would you agree then that this fallback logic is currently only executed when looking for the frameElement
of the AUT? Or are there any other cases as well that come to your mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it looks like it exists for aut or the edge case, but you are right it’s mainly for the cypress aut
Just checked in on this and saw it was merged - thanks for taking this over, gonna upgrade in our app today 😃 |
* 1.3.0 (#35) * feat: add option changing scrolling behavior (#30) * feat: allow changing scrolling behavior for realClick and realHover * feat: Fallback to Cypress.config('scrollBehavior') * feat: Add specs for scrollBehavior to click and hover * fix: ignore TS errors or Cypress <6.1.0 * fix: remove false option for scrollBehavior * fix: bump dev dependency for cypress to 6.1 for compilation error * [] Move scrollBehavior specs directly into click.spec and hover.spec * [] Fix failing swipe tests by passing scrollBehavior * Reduce renames * Remove unused option Co-authored-by: Dmitriy Kovalenko <[email protected]> * Add support for radius options in realTouch (#31) * test: add test for radius options in realTouch (#32) * fix(realTouch): accept 0 for position x/y values (#33) * feat: Transpile files to cjs (#34) * fix: calculate positions for elements inside iframes correctly (#29) * fix: calculate positions for elements inside iframes correctly * Handle iframes with scale transforms * [] Refactor getCypressElementCoordinates to better handle scaled frames * [] Add tests for click and hover in iframes * [] Add HTML files to fixtures folder * Remove unnecessary @ts-expect-error * Change logic of get cypress element * Make swipe tests retryable Co-authored-by: Dmitriy Kovalenko <[email protected]> * Fix touch radius test Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> * Revert "1.3.0 (#35)" This reverts commit db00220. * chore(readme): Add badge and fix typo Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]>
* 1.3.0 (#35) * feat: add option changing scrolling behavior (#30) * feat: allow changing scrolling behavior for realClick and realHover * feat: Fallback to Cypress.config('scrollBehavior') * feat: Add specs for scrollBehavior to click and hover * fix: ignore TS errors or Cypress <6.1.0 * fix: remove false option for scrollBehavior * fix: bump dev dependency for cypress to 6.1 for compilation error * [] Move scrollBehavior specs directly into click.spec and hover.spec * [] Fix failing swipe tests by passing scrollBehavior * Reduce renames * Remove unused option Co-authored-by: Dmitriy Kovalenko <[email protected]> * Add support for radius options in realTouch (#31) * test: add test for radius options in realTouch (#32) * fix(realTouch): accept 0 for position x/y values (#33) * feat: Transpile files to cjs (#34) * fix: calculate positions for elements inside iframes correctly (#29) * fix: calculate positions for elements inside iframes correctly * Handle iframes with scale transforms * [] Refactor getCypressElementCoordinates to better handle scaled frames * [] Add tests for click and hover in iframes * [] Add HTML files to fixtures folder * Remove unnecessary @ts-expect-error * Change logic of get cypress element * Make swipe tests retryable Co-authored-by: Dmitriy Kovalenko <[email protected]> * Fix touch radius test Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> * Revert "1.3.0 (#35)" This reverts commit db00220. * chore(readme): Add badge and fix typo * Update cypress to v8 Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]>
* chore: backport changes (#90) * 1.3.0 (#35) * feat: add option changing scrolling behavior (#30) * feat: allow changing scrolling behavior for realClick and realHover * feat: Fallback to Cypress.config('scrollBehavior') * feat: Add specs for scrollBehavior to click and hover * fix: ignore TS errors or Cypress <6.1.0 * fix: remove false option for scrollBehavior * fix: bump dev dependency for cypress to 6.1 for compilation error * [] Move scrollBehavior specs directly into click.spec and hover.spec * [] Fix failing swipe tests by passing scrollBehavior * Reduce renames * Remove unused option Co-authored-by: Dmitriy Kovalenko <[email protected]> * Add support for radius options in realTouch (#31) * test: add test for radius options in realTouch (#32) * fix(realTouch): accept 0 for position x/y values (#33) * feat: Transpile files to cjs (#34) * fix: calculate positions for elements inside iframes correctly (#29) * fix: calculate positions for elements inside iframes correctly * Handle iframes with scale transforms * [] Refactor getCypressElementCoordinates to better handle scaled frames * [] Add tests for click and hover in iframes * [] Add HTML files to fixtures folder * Remove unnecessary @ts-expect-error * Change logic of get cypress element * Make swipe tests retryable Co-authored-by: Dmitriy Kovalenko <[email protected]> * Fix touch radius test Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> * Revert "1.3.0 (#35)" This reverts commit db00220. * chore(readme): Add badge and fix typo Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> * chore(deps-dev): bump @typescript-eslint/parser from 4.24.0 to 4.26.0 (#92) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.24.0 to 4.26.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.26.0/packages/parser) Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @typescript-eslint/eslint-plugin (#91) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.25.0 to 4.26.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.26.0/packages/eslint-plugin) Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(Read * chore(deps-dev): bump cypress from 7.4.0 to 7.6.0 (#111) Bumps [cypress](https://github.com/cypress-io/cypress) from 7.4.0 to 7.6.0. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/.releaserc.base.js) - [Commits](cypress-io/cypress@v7.4.0...v7.6.0) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Remove validation of cypress iframe using id name (#124) * chore(deps-dev): bump @typescript-eslint/eslint-plugin (#122) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.26.0 to 4.28.3. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.28.3/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump cypress from 7.6.0 to 7.7.0 (#120) Bumps [cypress](https://github.com/cypress-io/cypress) from 7.6.0 to 7.7.0. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/.releaserc.base.js) - [Commits](cypress-io/cypress@v7.6.0...v7.7.0) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): Cypress v8 (#131) * 1.3.0 (#35) * feat: add option changing scrolling behavior (#30) * feat: allow changing scrolling behavior for realClick and realHover * feat: Fallback to Cypress.config('scrollBehavior') * feat: Add specs for scrollBehavior to click and hover * fix: ignore TS errors or Cypress <6.1.0 * fix: remove false option for scrollBehavior * fix: bump dev dependency for cypress to 6.1 for compilation error * [] Move scrollBehavior specs directly into click.spec and hover.spec * [] Fix failing swipe tests by passing scrollBehavior * Reduce renames * Remove unused option Co-authored-by: Dmitriy Kovalenko <[email protected]> * Add support for radius options in realTouch (#31) * test: add test for radius options in realTouch (#32) * fix(realTouch): accept 0 for position x/y values (#33) * feat: Transpile files to cjs (#34) * fix: calculate positions for elements inside iframes correctly (#29) * fix: calculate positions for elements inside iframes correctly * Handle iframes with scale transforms * [] Refactor getCypressElementCoordinates to better handle scaled frames * [] Add tests for click and hover in iframes * [] Add HTML files to fixtures folder * Remove unnecessary @ts-expect-error * Change logic of get cypress element * Make swipe tests retryable Co-authored-by: Dmitriy Kovalenko <[email protected]> * Fix touch radius test Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> * Revert "1.3.0 (#35)" This reverts commit db00220. * chore(readme): Add badge and fix typo * Update cypress to v8 Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> * chore(deps): Support cypress v8 * fix: Enter doesn't fire trust click event (#132) * fix: Enter doesn't fire trust click event * Commit fixture Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: Mateusz Burzyński <[email protected]> Co-authored-by: Izhaki <[email protected]> Co-authored-by: Kevin Fleischman <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Fixes #28
When
cy.realClick()
orcy.realHover()
are called on elements that are inside of an iframe within the Cypress app's own iframe, the position calculated for the element doesn't account for the possible offset position of its containing iframe.