Search code examples
reactjscypress

How can I use cypress with react image mapper?


When I try to automate clicking an image with Cypress I am getting an error.

I am using an image mapper to record my clicks. This is the code:

`\<ImageMapper
src={RighthandBatsmanPitchDefault}
width={300}
onLoad={() =\> load()}
onMouseDown={(area) =\> clicked(area)}
onMouseEnter={(area) =\> enterArea(area)}
onMouseLeave={(area) =\> leaveArea(area)}
onMouseMove={(area, \_, evt) =\> moveOnArea(area, evt)}
onImageClick={(evt) =\> clicked(evt)}
onImageMouseMove={(evt) =\> moveOnImage(evt)}
/\>

const enterArea = (area) =\> {
setHoveredArea(area);
};
const leaveArea = (area) =\> {
setHoveredArea(null);
};
const moveOnArea = (area, evt) =\> {
const coords = { x: evt.nativeEvent.layerX, y: evt.nativeEvent.layerY };
setCords(coords);
};

const clicked = (area) =\> {
props.parentWagonMsgData.parent = false;

    if ((props.positionBatTypeBatInput.waghoon_wheel_position_bat_type == "Right")) {
      if ((isInsideRectangle(Right_Hand_New_ShortFineLegFirst, cords) || isInsideRectangle(Right_Hand_New_ShortFineLegSecond, cords)) && (props.positionBatTypeBatInput.waghoon_wheel_position_bat_type == "Right")) {
        setMsgClick(`Short Fine Leg`);
        setRighthandBatsmanPitchDefault(RightHandBatsmanShortFineLeg);
      } else if ((isInsideRectangle(Right_Hand_New_DeepFineLegFirst, cords) || isInsideRectangle(Right_Hand_New_DeepFineLegSecond, cords)) && (props.positionBatTypeBatInput.waghoon_wheel_position_bat_type == "Right")) {
        setMsgClick(`Deep Fine Leg`);
        setRighthandBatsmanPitchDefault(RighthandBatsmanDeepFine);
      } else if ((isInsideRectangle(Right_Hand_New_SquareLegFirst, cords) || isInsideRectangle(Right_Hand_New_SquareLegSecond, cords)) && (props.positionBatTypeBatInput.waghoon_wheel_position_bat_type == "Right")) {
        setMsgClick(`Square Leg`);
        setRighthandBatsmanPitchDefault(RightHandBatsmanSqaureLeg);`

and so on... The definition of isInsideRectangle is :

export function isInsideRectangle({ x1, y1, x2, y2, x3, y3, x4, y4 }, { x, y }) {
let A = area(x1, y1, x2, y2, x3, y3) + area(x1, y1, x4, y4, x3, y3);
let A1 = area(x, y, x1, y1, x2, y2);
let A2 = area(x, y, x2, y2, x3, y3);
let A3 = area(x, y, x3, y3, x4, y4);
let A4 = area(x, y, x1, y1, x4, y4);
return A == A1 + A2 + A3 + A4;
}

I have tried multiple methods with Cypress including the simplest: cy.get(element).click() And I always get an error somewhat similar to this :

Error: TypeError: Cannot read properties of undefined (reading 'x') This is because x is undefined as cypress directly clicks on a location unlike physical mouse moving.

I have also tried in a somewhat indirect manner -

cy.get(this.wagon_wheel_locator)
.trigger("mouseenter", 120, 100)
.trigger("mousemove", 110, 100)
.trigger("mouseover", 110, 100)
.trigger("mousedown", 110, 100)
.wait(100)
.trigger("mouseup", 110, 100)
.trigger("mousemove", 130, 100)
.trigger("mouseleave", 130, 100);

This code doesn't give an error but it doesn't click either.

How can I click on the image via Cypress without getting the error ?


Solution

  • Often the results are better with plugin cypress-real-events especially where there are graphic elements that require coordinates.

    cy.get(wagon_wheel_locator)
      .realHover()                 // for hovering
      .realClick()                 // for clicking
    

    I also agree with Akiva, the error says

    Cannot read properties of undefined (reading 'x')

    but the code shows you do not set cords, which explains why it is undefined - it fits with the error message and you have const coords = ....

    So it could simply be a mis-spelling of the variable name that causes your issue.