Trigger method in cypress - cypress

I'm using drag and drop to move the node in canvas here. Drag and drop is working, but moving the node in canvas caused an uncaught expression error. I'm not sure what the problem is; I used the same code to move the nodes in the previous scenarios, and it worked fine.
const dataTransfer = new DataTransfer();
cy.get('[alt="sourcenode"]').trigger("dragstart", {
dataTransfer,
});
cy.get('.canvas')
.trigger("drop", { dataTransfer })
.trigger("mousemove",{force:true})
.trigger("mouseup", {force:true })
.trigger("mousemove", {
clientX: 700,
clientY: 150,
screenX: 700,
screenY: 150,
pageX: 700,
pageY: 150,
force:true
})
.trigger("mouseup", { force: true });
cy.get('.sourcenode in canvas').trigger("mousemove");
cy.get('.sourcenode in canvas').trigger("mouseup");

Related

Cypress: click and drag an image? mousedown & mousemove not working

I'm trying to test a gallery for the first time with Cypress but I'm having trouble trying to get the mouse events to work:
cy.get("img#front").should("be.visible");
cy.get("img#front")
.trigger("mousedown", { which: 1, pageX: 600, pageY: 100 })
.trigger("mousemove", { which: 1, pageX: -600, pageY: 100 })
.trigger("mouseup");
});
The image is visible on the page but when I do mouse down and mouse move on it nothing is happening. What I'm trying to do is press the mouse down and drag it left so the image changes to the next one in the gallery.
Using XY coordinates,
This is a simple example with the Cypress custom command, which I tried and it works for me,
* This reusable method is used to handle React drag and drop within cypress test.
*/
Cypress.Commands.add("dragAndDrop", (subject, target, dragIndex, dropIndex) => {
cy.get(subject).should("be.visible", { timeout: 2000 });
Cypress.log({
name: "DRAGNDROP",
message: `Dragging element ${subject} to ${target}`,
consoleProps: () => {
return {
subject: subject,
target: target
};
}
});
const BUTTON_INDEX = 0;
const SLOPPY_CLICK_THRESHOLD = 10;
cy.get(target).eq(dropIndex).then($target => {
let coordsDrop = $target[0].getBoundingClientRect();
cy.get(subject).eq(dragIndex).then(subject => {
const coordsDrag = subject[0].getBoundingClientRect();
cy.wrap(subject)
.trigger("mousedown", {
button: BUTTON_INDEX,
force: true
})
.trigger("mousemove", {
button: BUTTON_INDEX,
clientX: coordsDrag.x,
clientY: coordsDrag.y,
force: true
})
.wait(1000);
cy.get('body')
.trigger("mousemove", {
button: BUTTON_INDEX,
clientX: coordsDrop.x + SLOPPY_CLICK_THRESHOLD,
clientY: coordsDrop.y,
force: true
});
cy.get('body')
.trigger("mousemove", {
button: BUTTON_INDEX,
clientX: coordsDrop.x,
clientY: coordsDrop.y + SLOPPY_CLICK_THRESHOLD,
force: true
})
.wait(1000);
cy.get(target)
.trigger("mouseup");
});
});
});
in your cypress spec
cy.dragAndDrop(dragloc, droploc, 0, 0);
You can also try with a few changes
extracted from https://github.com/cypress-io/cypress/issues/3942
Click and drag within an image or canvas element has been the bane of my work-existence for a while. To be honest, I stumbled onto this post explicitly because I'm looking for something that will work in my current situation.
Do not be deterred, friend. I have a few examples that have worked for me in the past, hopefully this helps:
cy.get(".canvas-wrap > canvas")
.trigger("mousedown", 715, 155, {
button: 0,
force: true,
eventConstructor: "MouseEvent"
})
.trigger("mousemove", 100, 100, {
button: 0,
force: true,
eventConstructor: "MouseEvent"
})
.trigger("mouseup", 100, 100, {
button: 0,
force: true,
eventConstructor: "MouseEvent"
});
or
cy.get(".canvas-wrap")
.trigger("mousedown", 200, 200, { button: 0 })
.trigger("mousemove", { clientX: -250, clientY: -200 })
.trigger("mouseup", { force: true });
Anyway, I'd recommend experimenting with passing in button or event options, or just trying force: true and seeing if that gets you anywhere.
All the best

drag and drop with auto scrolling (dom-autoscrolling)

I have a list of text elements and want to automatically scroll my list to the bottom when I'm dragging my new element.
This example below works properly once I drag-and-dropped one time an element in a list.
I believe I need to call once an observable before the drag.
I'm using dragula and dom-autoscrolling.
import {takeUntil} from "rxjs/internal/operators/takeUntil";
import * as autoScroll from 'dom-autoscroller';
const drake = this.dragulaService.find(this.dragulaBagName);
this.dragulaService.drag.pipe(
takeUntil(this.destroyed$),
).subscribe(([bag, movingEl, containerEl]) => {
autoScroll(containerEl.parentNode, {
margin: 20,
pixels: 10,
scrollWhenOutside: true,
autoScroll: function () {
return this.down && drake && drake.drake && drake.drake.dragging;
}
});
});
Apparently, this.down in callback autoScroll is set to false at the beginning... once drag-and-dropped one time, it works correctly.
Any ideas?
try use (mousedown)="initAutoScroll()"
initAutoScroll(){
const drake = this.dragulaService.find(this.dragulaBagName);
this.scroll = autoScroll(
containerEl.parentNode,
{
margin: 30,
maxSpeed: 25,
scrollWhenOutside: true,
autoScroll: function () {
return this.down && drake.drake.dragging;
}
});
}
this.dragulaService.dragend.asObservable().subscribe(value => {
if (this.scroll) {
this.scroll.destroy(); // destroy when don't use auto-scroll
}
});

React native state change transitions

What is the best pattern, in react native, to animate components on state change?
For example I have a list of elements and tapping on one I want it to disappear and the ones below him to 'get up' filling the missing space
How can I make the transition smooth?
React-natives own animated API works really well.
Basically you have a value in state, which you connect with a style props, and change that value over time. (for examples follow link)
For smooth animations use usenativedriver (not always possible) and also, make sure you don't have debugger runnning in emulated/real device
EDIT: 2018-05-31
This is an example of how I've used it. Probably exist other ways of doing it
import { Animated, Text} from 'react-native';
class ShowCaseAnimation extends Component {
state = {
animations: {
height: new Animated.Value(0),
fade: new Animated.Value(0),
}
}
componentDidMount() {
const { height, fade } = this.state.animations;
if (this.props.animate) {
doneAnimation({ height, fade }).start(() => {
// Do stuff after animations
});
}
}
render() {
const { animations } = this.state;
return (
<Animated.View
style={{
height: animate? animations.height : 300,
opacity: animate? animations.fade: 1,
// other styling
}}
>
<Text> All your base are belong to us </Text>
</Animated.View>
);
}
}
*doneAnimation: *
import { Animated, Easing } from 'react-native';
export const doneAnimation = ({ height, fade }) => Animated.parallel([
Animated.timing(height, {
toValue: 300,
easing: Easing.elastic(),
duration: 500,
delay: 1500,
}),
Animated.timing(fade, {
toValue: 1,
easing: Easing.ease,
duration: 1000,
delay: 1500,
}),
]);
export default doneAnimation;
doneAnimation will change the state and perform the described animations.
This is how you can trigger an animation on state change in a functional component.
Say you have a Button that changes state with onPress:
<Button title="toggle" onPress={() => setValue(!Value)} />
then you can trigger the animation inside a useEffect with the Value
that changes in the dependency array:
const [Value, setValue] = useState(true);
useEffect(() => {
// Input your animation here
// ...
}, [Value]);

React navigation transition animations with useNativeDriver only run first time

I am using react-navigation Transitioner to create a custom StackNavigator. When using useNativeDriver: true in my transition configuration, the animation for the transition only runs the first time. When set to false, it works as expected.
Note: Whilst setting it to false does fix my problem, I get choppy performance on Android without it, even in production mode.
Below snippet is my navigation view
render() {
return (
<Transitioner
configureTransition={this._configureTransition}
navigation={this.props.navigation}
render={this._render}
/>
);
}
_configureTransition = () => {
return { useNativeDriver: true };
}
_render = (transitionProps) => {
return transitionProps.scenes.map(scene => this._renderScene(transitionProps, scene));
}
_renderScene = (transitionProps, scene) => {
const { layout, position } = transitionProps;
const { index } = scene;
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [layout.initWidth, 0, 0],
});
const animationStyle = {
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor: '#FFF',
transform: [{ translateX }],
};
const Scene = this.props.router.getComponentForRouteName(scene.route.routeName);
return (
<Animated.View key={scene.key} style={animationStyle}>
<Scene />
</Animated.View>
);
}
Below is a screen cap of the problem. Note how the first transition is animated, whilst future ones are not (the 'back' navigation should be animated too)

Transform too dense data

Trying to display line chart using plotly.js, my data are collected per second. I fed my graph but the result looks strange even if I zoom in, to very low detail where it should be displayed per seconds.
Are there any methods I could use to preprocess the data so it would display well in different scales (as I zoom in and out)?
var gd = document.getElementById('tester');
var layout = {
xaxis: {
showgrid: true,
tickformat: "%H:%M:%S",
},
margin: {
l: 40,
b: 40,
r: 30,
t: 20
},
hovermode: 'x',
};
var draw = function(data, layout) {
Plotly.newPlot(gd, data, layout, {
showLink: false,
displaylogo: false
});
};
var dataurl = 'https://gist.githubusercontent.com/fhurta/6c53839fbc91a363d62966a972a5e4a2/raw/2cd735f0b024e496164dacec92fa4a7abcd5da2e/series.csv';
Plotly.d3.csv(dataurl, function(rows) {
var data = [{
type: 'scatter',
x: rows.map(function(row) {
return new Date(row['Time']);
}),
y: rows.map(function(row) {
return row['Value1'];
}),
line: {
width: 1
}
}];
draw(data, layout);
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="tester" style="width:600px;height:300px;"></div>

Resources