Giter Site home page Giter Site logo

cypress-real-events's Introduction

Cypress Real Events

Fire native system events from Cypress

npm version npm version npm version

Stand With Ukraine

Why?

Cypress default events are simulated. That means that all events like cy.click or cy.type are fired from javascript. That's why these events will be untrusted (event.isTrusted will be false) and they can behave a little different from real native events. But for some cases, it can be impossible to use simulated events, for example, to fill a native alert or copy to the clipboard. This plugin solves this problem.

How?

Thanks to Chrome Devtools Protocol. Cypress is connecting to CDP for tasks like screenshots, setting viewport, and others. This project utilizes the same connection to fire system events. The event firing system works literally like in puppeteer. And as a result, unlocks such features like hovering and native focus management via Tab.

Requirements

Cypress only. Really. Cypress itself can fire native events. The only limitation for real events – they work only in the chromium-based browser. That means that Firefox is not supported, at least for now.

Quick overview

Here is a simple test that can be written with native events:

it("tests real events", () => {
  cy.get("input").realClick(); // perform a native real click on the field
  cy.realType("cypress real event"); // fires native system keypress events and fills the field
  cy.realPress("Tab"); // native tab click switches the focus
  cy.get("input").realMouseDown(); // perform a native mouse press on the field
  cy.get("input").realMouseUp(); // perform a native mouse release on the field
  cy.focused().realHover(); // hovers over the new focused element
  cy.contains("some text in the hovered popover");
});

Installation

Install npm package:

npm install cypress-real-events

yarn add cypress-real-events

Register new commands by adding this to your cypress/support/index.{js,ts} file.

import "cypress-real-events";

To include TypeScript declarations, add "cypress-real-events" to the types section of your tsconfig.json file:

{
  "compilerOptions": {
    "types": ["cypress", "node", "cypress-real-events"]
  }
}

API

The idea of the commands – they should be as similar as possible to cypress default commands (like cy.type), but starts with real – cy.realType.

Here is an overview of the available real event commands:

cy.realClick

Fires native system click event.

cy.get("button").realClick();
cy.get("button").realClick(options);

Example:

cy.get("button").realClick({ position: "topLeft" }); // click on the top left corner of button
cy.get("body").realClick({ x: 100, y: 1240 }); // click by the x & y coordinates relative to the whole window

Options:

  • Optional button: "none" | "left" | "right" | "middle" | "back" | "forward"
  • Optional pointer: "mouse" | "pen"
  • Optional x: undefined | number (more about coordinates)
  • Optional y: undefined | number (more about coordinates)
  • Optional position: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional scrollBehavior: "center" | "top" | "bottom" | "nearest" | false
  • Optional clickCount: number

Make sure that x and y have a bigger priority than position.

cy.realHover

Fires a real native hover event. Yes, it can test :hover preprocessor.

cy.get("button").realHover();
cy.get("button").realHover(options);

Example:

cy.get("button").realHover({ position: "bottomLeft" }); // hovers over the bottom left corner of button

Options:

  • Optional pointer: "mouse" | "pen"
  • Optional position: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional scrollBehavior: "center" | "top" | "bottom" | "nearest" | false

cy.realPress

Fires native press event. It can fire one key event or the "shortcut" like Shift+Control+M. Make sure that event is global, it means that it is required to firstly focus any control before firing this event.

cy.realPress("Tab"); // switch the focus for a11y testing
cy.realPress(["Alt", "Meta", "P"]); // Alt+(Command or Control)+P

Usage

cy.realPress(key);
cy.realPress(key, options);

Parameters:

Name Type Default value Description
key string | string[] - key or keys to press. Should be the same as cypress's type command argument. All the keys available here
options Options {}

Options:

  • Optional pointer: "mouse" | "pen"

cy.realTouch

Fires native system touch event.

cy.get("button").realTouch();
cy.get("button").realTouch(options);
Usage:
cy.get("button").realTouch({ position: "topLeft" }); // touches the top left corner of button
cy.get("body").realTouch({ x: 100, y: 1240 }); // touches the x & y coordinates relative to the whole window

Options:

  • Optional x: undefined | number (more about coordinates)
  • Optional y: undefined | number (more about coordinates)
  • Optional position: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional radius: undefined | number default 1
  • Optional radiusX: undefined | number default 1
  • Optional radiusY: undefined | number default 1

cy.realType

Runs a sequence of native press events (via cy.realPress). This can be used to simulate real typing. Make sure that type of event is global. This means that it is not attached to any field.

cy.realType("type any text"); // type any text on the page

cy.get("input").focus();
cy.realType("some text {enter}"); // type into focused field

Usage:

cy.realType(text);
cy.realType(text, options);

Parameters:

Name Type Default value Description
text string - text to type. Should be around the same as cypress's type command argument (https://docs.cypress.io/api/commands/type.html#Arguments. All the keys available here
options Options {}

Options:

  • Optional delay: undefined | number default 30
  • Optional log: undefined | false | true default true
  • Optional pressDelay: undefined | number default 10

cy.realSwipe

Runs native swipe events. It means that touch events will be fired. Actually a sequence of touchStart -> touchMove -> touchEnd. It can perfectly swipe drawers and other tools like this one.

Make sure to enable mobile viewport :)

cy.get(".element").realSwipe("toLeft"); // swipes from right to left
cy.get(".element").realSwipe("toRight"); // inverted

Usage:

cy.realSwipe(direction);
cy.realSwipe(direction, options);

Parameters:

Name Type Default value Description
direction "toLeft" | "toTop" | "toRight" | "toBottom"; - Direction of swipe
options Options {}

Options:

  • Optional length: undefined | number default 10
  • Optional step: undefined | number default 10
  • Optional x: undefined | number (more about coordinates)
  • Optional y: undefined | number (more about coordinates)
  • Optional touchPosition: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional touchMoveDelay: undefined | number default 0

cy.realMouseDown

Fires native system mouse down event.

cy.get("button").realMouseDown();
cy.get("button").realMouseDown(options);

Example:

cy.get("button").realMouseDown({ position: "topLeft" }); // click on the top left corner of button

Options:

  • Optional pointer: "mouse" | "pen"
  • Optional position: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional scrollBehavior: "center" | "top" | "bottom" | "nearest" | false
  • Optional button: "left" | "middle" | "right" | "back" | "forward" | "none"

cy.realMouseUp

Fires native system mouse up event.

cy.get("button").realMouseUp();
cy.get("button").realMouseUp(options);

Example:

cy.get("button").realMouseUp({ position: "topLeft" }); // click on the top left corner of button

Options:

  • Optional pointer: "mouse" | "pen"
  • Optional position: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional scrollBehavior: "center" | "top" | "bottom" | "nearest" | false
  • Optional button: "left" | "middle" | "right" | "back" | "forward" | "none"

cy.realMouseMove

Fires native system mouseMoved event. Moves mouse inside a subject to the provided amount of coordinates from top left corner (adjustable with position option.)

cy.get("sector").realMouseMove(x, y);
cy.get("sector").realMouseMove(x, y, options);

Example:

cy.get("sector").realMouseMove(50, 50, { position: "center" }); // moves by 50px x and y from center of sector

Options:

  • Optional position: "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"
  • Optional scrollBehavior: "center" | "top" | "bottom" | "nearest" | false

cy.realMouseWheel

Fires native system mouse wheel event, scrolls the page.

cy.get("div").realMouseWheel(options);

Example:

cy.get("div").realMouseWheel({ deltaY: 100 }) // Scroll down, mouse will be positioned at centered by default.
cy.get("div").realMouseWheel({ deltaY: -100 }) // Scroll up, mouse will be positioned at centered by default.
cy.get("div").realMouseWheel({ deltaX: 500 }) // Scroll right, mouse will be positioned at centered by default.
cy.get("div").realMouseWheel({ deltaX: -500 }) // Scroll left, mouse will be positioned at centered by default.
cy.get("div").realMouseWheel({ deltaY: 100, deltaX: 100 }) // Scroll right and down, mouse will be positioned at centered by default.

Options:

  • Optional scrollBehavior: "center" | "top" | "bottom" | "nearest" | false
  • Optional deltaX: X delta in CSS pixels for mouse wheel event (default: 0). Positive values emulate a scroll right and negative values emulate scroll left event.
  • Optional deltaY: Y delta in CSS pixels for mouse wheel event (default: 0). Positive values emulate a scroll down and negative values emulate a scroll up event.

Coordinates

Several commands from this plugin accept { x: number, y: number } coordinates. There is an important note that these coordinates are relative to the whole tab to pass it right to the CDP. For regular elements, we calculate them automatically, but if you need to pass absolute coordinates you will need to provide them yourself.

The easiest way to debug coordinates is to run any real events command and check the logged coordinates by clicking on the command.

checking coordinates example

FAQ

1. Why cy.realHover hovering state does not show in the visual regression services?

Unfortunately, neither visual regression services like Happo and Percy nor plain cy.screenshot do not allow to test the hovering state. The hovering state is very different from any kind of js and css so it is not possible to capture it using dom snapshotting (like visual regression services do) and the screenshooting as well because cypress core itself is preventing hovering state in the screenshots.

2. When I am doing cy.realHover hovering state is not resetting after my checks

Let's take an example. If the real user needs to open menu popover then do check content of popover content and close it the algorithm will be:

  1. Hover menu
  2. Check the content
  3. Put mouse away from the popover

To automate this with cypress, you can do the following

cy.get("[aria-label='Test Button']")
  .should("have.css", "background-color", "rgb(217, 83, 79)") // check the state before hover
  .realHover()
  .should("have.css", "background-color", "rgb(201, 48, 44"); // test hovering state

// reset hovering by putting mouse away (e.g. here top left corner of body)
cy.get("body").realHover({ position: "topLeft" });
// hover state reset 🎉
cy.get("[aria-label='Test Button']").should(
  "have.css",
  "background-color",
  "rgb(217, 83, 79)"
);

3. Why do I get "Are You Sure" popups when I am using real events and why I do not get them while using the normal cypress clicks?

Sometimes when there are unsaved changes in a webform, and you leave the page, the web application asks you due the onbeforeunload event if you really want to leaf the page and loose the changes.

You can try it on this Demo Page.

In "normal" Cypress tests, these popup windows do not appear. This is because no "real" user actions are performed on the application. See this page for more information about the beforeunload event. But when they appear, they block the whole test execution, and you have to handle them explicitly. Gleb Bahmutov writes about this behaviour and possible solutions in this Blog Post.

Now when you use this real-events plugin and perform a realEvent on your application, the browser thinks there happened a real user interaction. From now on your test is in an active interaction state, which allows the application to use all the features listed here.

UX

One problem of the real native system events I need to mention – you will not get an error message if the event wasn't produced. Similar to selenium or playwright – if a javascript event was not fired you will not get a comprehensive error message.

So probably this package should not be used as a replacement for the cypress events, at least for the writing tests experience 🐨

License

The project is licensed under the terms of MIT license

cypress-real-events's People

Contributors

adamistheanswer avatar alirezamirian avatar amoshydra avatar andarist avatar arjunpatel17 avatar christine-pinto avatar denysdovhan avatar dependabot-preview[bot] avatar dependabot[bot] avatar dmtrkovalenko avatar dolevbitran avatar drecali avatar fernyb avatar illright avatar im-a-train avatar istateside avatar izhaki avatar jbard1 avatar joshwooding avatar kokogino avatar martinsik avatar mehmetyararvx avatar minilfat avatar mitchwd avatar nicholasboll avatar nicklemmon avatar noahgelman avatar piwysocki avatar rahulraj97 avatar snapris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cypress-real-events's Issues

Focus the AUT before actions

I think that for the majority of use cases (if not for all of them, maybe except tabbing) it makes sense to focus the AUT - without that some commands might not work properly.

I'm implementing global keyboard commands in our app so I want to use smth like to prepare the app for the assertion:

cy.realPress(['Shift', '1']);

However, this won't work because the AUT is not focused so my keyboard listener that lives in it has no chance of receiving this input.

I've tried this:

cy.get('body').focus();
cy.realPress(['Shift', '1']);

but it doesn't work even though after this we get:

cy.window().then(win => win.document.hasFocus() === true)

I've worked around my issue with:

cy.get('body').realClick({ position: 'topLeft' });
cy.realPress(['Shift', '1']);

but it feels that it could work "out of the box". I'm not entirely sure what exact command would be best to shift focus properly to the AUT before performing an action since a real click is not good in the sense that it could invoke some other, unrelated, stuff in the AUT.

After I call the realHover() method over a menu and perform other actions, the menu is still opened

Hi @dmtrKovalenko I apologize for not posting it on the first place. I cannot show the actual behavior here as I cannot post anything related to my company code, but basically I have this code block

cy.get(this.menuNavBarMainReportsCSS).realHover(); // After this line is executed, the menu is still opened, like the hover didn't go away.

cy.get(this.menuNavBarItemClassicReportsCSS).realHover(); // I did this to hover over another element within that menu that expands when I hover in the first one, and it solves the problem.

cy.get(this.menuNavBarItemClassicReportsCSS).click();


Would this suffice? Thanks again for your time and apologies again

Implement cy.realUpload

Task cy.realUploadwill upload file from the file system. It should work similar to https://github.com/abramenal/cypress-file-upload/ but upload the file using CDP.

This command will require a plugin to be registered.

It is possible using a puppeteer, so it should (https://dev.to/sonyarianto/practical-puppeteer-how-to-upload-a-file-programatically-4nm4) and we should be able to attach input file using DOM.setFileInputFiles CDP command instead of javascript-based approach

cy.get("input").realUpload("filename.jpg")

realTouch() Absolute Coordinates does not respect Viewport size

Hi,

I have the viewport size set in a Cypress test to cy.viewport(1280, 720);, however the realTouch() does not always have the correct absolute coordinates when the browser is resized - I believe this is because the coordinates are calculated based on the iframe rather than the Html or Body element of the page.

For example, if I run my test on a full page width, the calculated absolute coordinates are x: 1254 and y: 177. If I resize my window, the coordinates change to x:1221 and y:177, even though my viewport is locked to 1280x720px.

image

image

Shift+Tab syntax

Hi, loving the plugin so far.

I have a question about the syntax for Shift+Tab. I can't seem to get the syntax right without throwing an error. Can you add an example of multi-key pressing to the README?

Implement cy.realDownload

Implement file downloading using real cypress event.

The main idea that it should download the file to the temporary directory in the file system (e.g. /tmp) or in any other directory user set to using Page.setDownloadBehavior.

This file will require a plugin registered.

cy.get("a#download").realDownload()
cy.get("a#download").realDownload("absolute/path")
cy.get("a#download").realDownload("./realative/to/the/project/path").then(file => {
  console.log(file.size)
  console.log(file.path)
  // and any other valuable info about file 
})

Use more predictable units for offset positions

@dmtrKovalenko has mentioned that the used coordinate system is not intuitive to Cypress users. I partially agree with that - I think though that the internal coordinate system is mostly hidden from users and they don't have to care about it that much because cypress-real-events is taking care of the heavy-lifting and computes the screen positions of AUT elements.
#198 (comment)

I think though that there is one thing that could be done to make interacting with this library more intuitive and preditable

Currently, if we do smth like:

cy.get('div').realClick({ position: {  x: 5, y: 5 } })

then the computed position will use { x: 5, y: 5 } as a screen offset of the element's position. I don't think this is what users expect though, for the majority of use cases. This is especially less-than-ideal as the final position is depending on the screen size and can vary based on the whole window being resized or devtools being open etc

I propose to redefine what this offset means - IMHO this should be an offset from the el.getBoundingClientRect(). That way we'd end up with more consistent results, independent from the root viewport size.

The change should be pretty trivial (but breaking!) - we'd have to essentially shift the logic from getPositionedCoordinates to getElementPositionXY (the latter should probably be renamed in the process).

Using `.real[action]` commands forces a `scrollIntoView`, regardless of Cypress scrollBehavior/force options

Hey folks. Big fan of the library, helped me get through some tricky issues with :hover styling in Cypress tests.

I've been tracking down an issue with one of my tests using cy.realHover. The page scrolls, and then the wrong element ends up getting hovered. I'm not 100%, but I think the wrong element is being hovered because the element has changed positions after scrolling?

Regardless of the wrong element being hovered- I didn't expect that realHover would force the element to be scrolled into view. realHover (and I believe the other action commands) uses getCypressElementCoordinates, which calls htmlElement.scrollIntoView.

By default, Cypress does scroll the page when you interact with elements on the page, but you can customize that behavior by passing { scrollBehavior: string|false } in Cypress >=6, or { force: true } in Cypress <=5. You can also set the scrollBehavior as a global option in your cypress.json file..

I would expect cypress-real-events to respect that scrollBehavior option if given, or at the least, not force a scroll on elements that are already visible on the page.

I am not familiar at all with how the CDB protocol works, so there may be a reason this is required that I'm unaware of.

I've got a quick patch I'm working on that I'll put up as a PR soon. Happy to close it if there's something I'm missing here.

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project ✨

Your semantic-release bot 📦🚀

Real Press Arrow keys not working on Mac

Confirmed by a coworker. Using the latest version of cypress-real-events and cypress, Using Real Press with the arrow keys down not function properly in a Mac environment.

Not able to type in a text box

AUT :- https://www.webdriveruniversity.com/Contact-Us/contactus.html
Cypress version : 6.0.0

describe('testing real event plugin', () =>{

    it('should ne able to test', () =>{

        cy.visit('https://www.webdriveruniversity.com/Contact-Us/contactus.html')
        cy.get('[name="first_name"]').realType('Automation')

    })
})

I found 2 issues:-

  1. I am not able to realtype
  2. As shown in the screenshot, code is realType, however, in runner, we see it as realPress

Screenshot 2020-11-27 at 12 31 52

Error in firefox component testing

I have a simple component test and I am trying to do

cy.get('[name="number"]').realType('asd');

But I am getting the following error:
image
The only error in console is:

Uncaught TypeError: Cypress is undefined

This is working properly in Chrome.

Cypress version: 9.0.0
cypress-real-events version: 1.5.1

'Enter' functionality was not implemented correctly and does not work

Testing out the new Enter function, it is not working correctly.

The Enter information is being passed in via an object key: Link to code

The Enter key data needs to be a part of the top level object, not its' own object inside a key.

You can have a button that console logs a message when clicked and the new enter functionality will not work. Moving the enter data to the top level of the object fixes it

Real click not working when scrolling is used

I am testing a video where the click on the middle of the scrubber bar is meant to be clicked by .realClick({ position: 'center' }); and test that the current time of the video has elapsed a certain amount.

However, with the inclusion of this.focusRef.current.scrollTop = 0; which scrolls the entire component, the test becomes flaky and 30-40/100 times the scrubber bar is focused but can't click be on.

Tried with:
Chrome 89
Node 12.20.1
cypress 6.8.0
cypress-real-events 1.3.0
yarn

Make pointer-related commands "dual"

It would be nice if I could just do this:

cy.realClick({ x: 10, y: 10 })

instead of having to do this

cy.get('body').realClick({ x: 10, y: 10 })

Issue installing with Typescript

Getting SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' when installing on cypress/ typescript

Installed using npm install cypress-real-events --save-dev

Added import "cypress-real-events/support"; to cypress/support/index.js

"compilerOptions": {

"target": "ES6",                         
"module": "commonjs",                    
 "lib": [
    "DOM",
    "ES6"
], 

Is there a different setup required? Tried moving import statement to support/commands.js, code compiles but get 'cy.realpress is not a function when method called.

Compatibility with Cypress 9

Would it be possible to relax the version constraint in package.json to include Cypress 9 or does some work need to be done first to make this library compatible?

Typo in `cy.realMouseMove` code example in README

The code example for cy.realMouseMove is using cy,realMouseUp

Currently the code example for cy.realMouseMove in README.md is:

cy.get("sector").realMouseUp(50, 50, { position: "center" }); // moves by 50px x and y from center of sector

I think the correct example should be:

cy.get("sector").realMouseMove(50, 50, { position: "center" }); // moves by 50px x and y from center of sector

Link to relevant README section https://github.com/dmtrKovalenko/cypress-real-events#cyrealmousemove

Link to the specific text I'm referring to: https://github.com/dmtrKovalenko/cypress-real-events#:~:text=cy.get(%22sector%22).-,realmouseup(50%2C%2050,-%2C%20%7B%20position%3A%20%22center%22%20%7D)%3B%20%2F%2F%20moves

@dmtrKovalenko thank you for creating and maintaining such a useful Cypress plugin!

Please let me know if there are other issues or consideration and what the next steps should be. According to the contributing guidelines we should make an issue first. I was tempted to make a PR directly but I started with an issue and will follow the next steps when I hear back from you.

Implement swipe command

Swipe command

cy.get("element").realSwipe("left-to-right")
cy.get(element).realSwipe("right-to-left")
cy.get(element).realSwipe("bottom-to-top", { swipeWidth: 100 })
cy.get(element).realSwipe("top-to-bottom")

`.realHover()` effect is not captured in `cy.screenshot()`

Hi @dmtrKovalenko ,
first of all thank you for this amazing library!

I was trying to use realHover() in combination with Cypress cy.screenshot(). While I can easily see the effect of real hover in test GUI, the moment the screenshot is taken, that effect is gone.

On top of that, the hover effect doesn't persist even in Cypress' own DOM snapshots (in the GUI runner). Please see the GIF below:
https://share.getcloudapp.com/Z4uoRyem

Is there any way this effect can be persisted (forced?) or are there technical limitations obstructing that?
Thank you in advance and please let me know if I can provide more details.

`realMouseMove()` uses hardcoded position "topLeft"

I think the cy.realMouseMove() command has a hardcoded position as seen below.

const basePosition= getCypressElementCoordinates(
subject,
"topLeft",
options.scrollBehavior
);

I tried to use it with position: center as in the code example below but the event happened in the same hardcoded topLeft position.

cy.get("sector").realMouseMove(50, 50, { position: "center" }); // moves by 50px x and y from center of sector

I made Cypress test cases for all Cypress positions listed here:

export type Position =
| "topLeft"
| "top"
| "topRight"
| "left"
| "center"
| "right"
| "bottomLeft"
| "bottom"
| "bottomRight"

Here is the pattern for my Cypress tests.:

cy.get("body")
  .realMouseDown()
  .realMouseMove(20, 10, { position: "topLeft" })
  .realMouseMove(30, 20, { position: "topLeft" })
  .realMouseUp();
cy.get("body")
  .realMouseDown()
  .realMouseMove(20, 10, { position: "top" })
  .realMouseMove(30, 20, { position: "top" })
  .realMouseUp();
cy.get("body")
  .realMouseDown()
  .realMouseMove(-20, 10, { position: "topRight" })
  .realMouseMove(-30, 20, { position: "topRight" })
  .realMouseUp();

Outcomes

Ideal Current
image image

Currently, the marks are all overlapping. Ideally, they should all be in different positions according to the options given to cy.realMouseMove()

Implement in realClick, realSwipe, realTouch the support for percentages regarding x and y

It should be possible to interact with those commands also with percentages

as an example

cy.get("body").realClick({ x: `10%`, y: `12%` })

cy.get("body").realSwipe({ x: `10%`, y: `12%` })

cy.get("body").realTouch({ x: `10%`, y: `12%` })

or to keep intact the current x and y it could be

cy.get("body").realClick({ xPercent: `10%`, yPercent: `12%` })

cy.get("body").realSwipe({ xPercent: `10%`, yPercent: `12%` })

cy.get("body").realTouch({ xPercent: `10%`, yPercent: `12%` })

Expand the set of allowed characters for realType()

I would like to be able to type special language specific characters with realType. For example the german characters "ö", "ä", "ü".

cy.get('test').realType('Bär')

It would be nice if I would be able to extend the keyCodeDefinitions at runtime.

Real Click not working on GithubAction

I recently added the dependency to my project which is running on github action , for some reason locally works fine, but on the github action when runs, then I got this error:

CypressError: cy.click() can only be called on a single element. Your subject contained 2 elements. Pass { multiple: true } if you want to serially click each element.

"react": "^16.13.1",
"cypress": "^5.3.0",

any ideas??

Cypress Iframe Handling - Failure to interact with Button

I am trying to E2E test an auth flow with Cypress that includes a third party method called BankID. BankId is integrated through three nested iframes that I can successfully access. However, when I type into the input field via cy.type('12345678912'), BankId does not register this as trusted events and never unlocks the submit button with the arrow.

When using your package via cy.realType('12345678912'), it actually succeeds in unlocking the submit button. However i can never successfully click the submit button, neither with .click() or even the package method .realClick().

The error is: "Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'."

I uploaded a sample repository with a minimal testing version here.

Any feedback or hints would be greatly appreciated :)

Here is the relevant code:

   
/// <reference types="cypress" />
import { skipOn } from '@cypress/skip-test'

describe('Recipe: blogs__iframes', () => {
  skipOn('firefox', () => {
    it('do it more generically', () => {
      const getIframeBody = (identifier) => {
        return cy
        .get(identifier)
        .its('0.contentDocument.body')
        .should('not.be.empty')
        .then(cy.wrap)
      }

      // Visiting the page index.html and getting iframe A
      cy.visit('index.html').contains('XHR in iframe')
      getIframeBody('iframe[data-cy="bankid"]').as('iframeA')

      cy.get('@iframeA').within(() => {
        getIframeBody('iframe[src="https://tools.bankid.no/bankid-test/auth"]').as('iframeB')

        cy.get('@iframeB').within(() => {
          getIframeBody('iframe[src^="https://csfe.bankid.no/CentralServerFEJS"]').as('iframeC')

          // Now we are in the right place and it finds the correct input element.
          // However, normal cypress command .type() fails and we have to use library cypress-real-events,
          // which provides an event firing system that works literally like in puppeteer
          cy.get('@iframeC').find('input[type="tel"]').should('be.visible').realType('12345678912')

          // But for the button below, this library now doesn't help anymore:
          // "Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'."
          cy.get('@iframeC').find('button[type="submit"]').should('be.visible').first().realClick()
        })
      })
    })
  })
})

RealPress not firing click events on button elements

Hi there, thanks for the great project! I was excited to find it since I ran into issues with Cypress not firing native events (and it not being on their roadmap). This tool is promising for keyboard accessibility testing! But as far as I can tell, the Enter key still doesn't work the same way browsers do as of version 1.5.1. Specifically, hitting the Enter key on a Button element should fire a native click event and handler callback function. In Cypress-Real-Events, the event is getting lost somewhere in the stack. The tests added in #69 work for putting text into an Input element, but not firing a callback function on an interactive element's click handler.

I looked into the code a bit and saw RealPress is successfully catching the user event and firing off Input.dispatchKeyEvent to the DevTools protocol. But on multiple repos where I tested it, the click handler attached to a button won't fire on the Enter key. This is important for writing keyboard accessibility tests that mimic user behavior, so we can differentiate between things like <div tabindex="0" onclick="handleClick()"> and <button onclick="handleClick()>, where the div will fail to function without a key handler but the button will click on Enter.

How to test

I've added a failing test for this behavior in my fork, I'd be happy to submit a PR for it: marcysutton@70f8b73

Here's a live test page I made where you can compare the user experience with your keyboard to what Cypress-Real-Events is doing: https://marcy.codes/testing/cypress-real-events/

Screenshots

In my test page, when a user presses the Enter key on a button element it appends text to a DIV:
Cypress Test page showing a focused button and event details appended to the screen

With Cypress-Real-Events, the text is never appended to the DIV when .realPress('Enter') is fired on the button:
Cypress App opened to a RealPress test showing the button failing to operate


If you have any tips (and if I'm not missing something obvious), I could potentially work on a PR. I'd love to get this working. Thanks!

Implement drag and drop

Implement the native dnd command. It should look like

cy.get("button").realDnD("button.button2")
cy.get("button").realDnD({ x: 100, y: 100 })

cy.press() is not a function

as per the document, cy.press() function exists
however, when I used, cypress throws error cy.press() saying is not a function

However, Intellisense, shows, cy.realPress() function.

May be its a typo in documentation.

Missing example/usage for options for realHover in the ReadMe

Current behaviour

The user wants to change options for realHover but they can't find any examples in the ReadMe/Documentation showing how to do that. Instead, the user needs to google for an example or needs to trial and error through their code.

Expected behaviour

The options for realHover have an example showing how to implement these options for realHover

ToDo

Add an example/usage (I can do that as I have been through the current behaviour and found a solution)

Updating to work with Cypress v7.x

Hi:

We are currently beholden to Cypress v6.9.1 and cannot upgrade to the latest v7.x because of the following.

When running node v14.15.4, an error message is produced by cypress-real-events stating the following (in Node v12.21, this is a warning, not an error message):

npm ERR! Could not resolve dependency:
npm ERR! peer cypress@"^4.x || ^5.x || ^6.x" from [email protected]
npm ERR! node_modules/cypress-real-events
npm ERR!   dev cypress-real-events@"^1.3.0" from the root project

I haven't taken a look at cypress-real-events code to see why this version threshold exists; is there a reason why? Then, based off of that answer, what would it take to become compatible with Cypress v.7.x?

Thanks!

Typescript support

Something seems off with typescript support in VS Code.
Following the recommended config results in "Property 'realHover' does not exist on type 'Chainable<JQuery>'." in VS Code but runs in cypress.

Vs Code appears to be looking at support.d.ts which only contains "export {};"

Changing the index.ts command from "import 'cypress-real-events/support';" to "import 'cypress-real-events/index';" resolves the error in VS Code but errors out when cypress runs.

Implement a .realActive() method

Implement a method for showing an html element's active state. cy.realActive() will put the element in the active state to check for active styling/behavior.

Use case: To check css active state styles/behavior of an element.

cy.get('button').realActive()

Library does not work on windows chrome

The library does not work on Windows chrome BUT seems to work on Windows headless and Linux.
Tested it with realHover and realClick.

Tried with:

  • Chrome 89
  • Node 12.18.3
  • cypress 6.5.0 & 6.8.0
  • typescript
  • cypress-real-events 1.2.0 & 1.3.0
  • yarn
  • vite

Test runner interferes with tabbing

When starting a test with cy.realPress('Tab'); it tabs through the cypress window before tabbing through the webpage.

Tried with:
Chrome 89
Node 12.20.1
cypress 6.8.0
cypress-real-events 1.3.0
yarn

Triggering events on elements inside iframes calculate position incorrectly

I've been using cypress-real-events in the Cypress tests for our app. Our app renders a page inside of an <iframe>.

I've noticed that the events triggered on elements within that iframe are being triggered in the wrong positions, sometimes affecting elements other than the one we're calling the .realAction() commands on.

While looking into #26, I tracked down the problem here to getCypressElementCoordinates

  const { x, y, width, height } = htmlElement.getBoundingClientRect();
  const [posX, posY] = getPositionedCoordinates(
    x,
    y,
    width,
    height,
    position ?? "center"
  );


  return {
    x: appFrameX + (window.pageXOffset + posX) * appFrameScale,
    y: appFrameY + (window.pageYOffset + posY) * appFrameScale,
  };

This doesn't account for the case where the htmlElement is inside of an iframe nested inside of the appFrame. In that situation, htmlElement.getBoundingClientRect() returns coordinates relative to its closest iframe.

For us, that nested iframe was positioned 50px from the top of the app Frame, so all of the events triggered with this library were firing 50px higher than we wanted.

Make it possible to perform actions while pressing a particular key or pointer button

To test some interactions we might have to do multiple things at once - like for example press space and move the pointer around while holding the left button of the mouse down to perform a "pan" in a canvas-based app (like in Figma, Excalidraw and more)

Should we introduce cy.realPressDown and cy.realPressUp to allow this? With this in place it should be possible to perform this sequence in a test - although it would be nice to also get some command for moving the pointer and this is related to #17

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.