Skip to content

Commit 92698af

Browse files
committed
Working version from CLI
1 parent 18f6ebe commit 92698af

File tree

9 files changed

+457
-82
lines changed

9 files changed

+457
-82
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
cypress/integration/monkey/node_modules/
1+
cypress/integration/monkey/node_modules/
2+
cypress/screenshots
3+
cypress/videos

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Cypress Random Tester (Monkey)
2+
This repository contains the code for a random tester developed using [Cypress](https://www.cypress.io/). Two versions are developed, including a full random tester and a smarter random tester, and the differences between these two remain in the type of commands that each can execute. The detail is explained in sections below
3+
4+
## How to run

cypress.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

cypress/integration/cypress.env.json

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
//Imports
2+
require('cypress-plugin-tab');
3+
4+
const url = Cypress.env('baseUrl') || "https://uniandes.edu.co/";
5+
const appName = Cypress.env('appName')|| "your app";
6+
const events = Cypress.env('events')|| 100;
7+
const delay = Cypress.env('delay') || 100;
8+
9+
const pct_clicks = Cypress.env('pctClicks') || 19;
10+
const pct_scrolls = Cypress.env('pctScroll') || 17;
11+
const pct_selectors = Cypress.env('pctSelectors') || 16;
12+
const pct_keys = Cypress.env('pctKeys') || 16;
13+
const pct_spkeys = Cypress.env('pctSpKeys') || 16;
14+
const pct_pgnav = Cypress.env('pctPgNav') || 16;
15+
16+
17+
function getRandomInt(min, max) {
18+
min = Math.ceil(min);
19+
max = Math.floor(max);
20+
return Math.floor(Math.random() * (max - min)) + min;
21+
};
22+
23+
24+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
25+
//Start of random monkey
26+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
27+
28+
var curX = 0;
29+
var curY = 0;
30+
var focused = false;
31+
32+
function randClick(){
33+
let viewportHeight = Cypress.config("viewportHeight");
34+
let viewportWidth = Cypress.config("viewportWidth");
35+
let randX = getRandomInt(curX, viewportWidth);
36+
let randY = getRandomInt(curY, viewportHeight);
37+
38+
cy.window().then((win)=>{
39+
let element = win.document.elementFromPoint(randX, randY);
40+
if(!!element){
41+
//Use cypress selector if any fits
42+
if(!!element.id){ //boolean that indicates if the element has a non-empty id
43+
cy.get(`#${element.id}`).click();
44+
}
45+
else if(!!element.className){ //boolean that indicates if the element has a non-empty className
46+
let className = element.className.split(" ")[0];
47+
cy.get(`.${className}`).then($candidates => {
48+
//click the first visible candidate
49+
for(let i = 0; i < $candidates.length; i++){
50+
let candidate = $candidates.get(i);
51+
if(!Cypress.dom.isHidden(candidate)){
52+
cy.wrap(candidate).click({force:true});
53+
}
54+
}
55+
});
56+
}
57+
else{
58+
cy.get(element.tagName).then($candidates => {
59+
//click the first visible candidate
60+
for(let i = 0; i < $candidates.length; i++){
61+
let candidate = $candidates.get(i);
62+
if(!Cypress.dom.isHidden(candidate)){
63+
cy.wrap(candidate).click({force:true});
64+
}
65+
}
66+
});
67+
68+
}
69+
}
70+
else{
71+
cy.get('body').click(randX, randY, {force:true});
72+
}
73+
focused = !!win.document.activeElement;
74+
75+
})
76+
}
77+
78+
function randDClick(){
79+
let viewportHeight = Cypress.config("viewportHeight");
80+
let viewportWidth = Cypress.config("viewportWidth");
81+
let randX = getRandomInt(curX, viewportWidth);
82+
let randY = getRandomInt(curY, viewportHeight);
83+
84+
cy.window().then((win)=>{
85+
console.log(win.document)
86+
let element = win.document.elementFromPoint(randX, randY);
87+
console.log(element)
88+
if(!!element){
89+
//Use cypress selector if any fits
90+
if(!!element.id){ //boolean that indicates if the element has a non-empty id
91+
cy.get(`#${element.id}`).dblclick();
92+
}
93+
else if(!!element.className){ //boolean that indicates if the element has a non-empty className
94+
let className = element.className.split(" ")[0];
95+
cy.get(`.${className}`).then($candidates => {
96+
//dblclick the first visible candidate
97+
for(let i = 0; i < $candidates.length; i++){
98+
let candidate = $candidates.get(i);
99+
if(!Cypress.dom.isHidden(candidate)){
100+
cy.wrap(candidate).dblclick({force:true});
101+
}
102+
}
103+
});
104+
}
105+
else{
106+
cy.get(element.tagName).then($candidates => {
107+
//dblclick the first visible candidate
108+
for(let i = 0; i < $candidates.length; i++){
109+
let candidate = $candidates.get(i);
110+
if(!Cypress.dom.isHidden(candidate)){
111+
cy.wrap(candidate).dblclick({force:true});
112+
}
113+
}
114+
});
115+
}
116+
}
117+
else{
118+
cy.get('body').dblclick(randX, randY, {force:true});
119+
}
120+
focused = !!win.document.activeElement;
121+
})
122+
}
123+
124+
function randRClick(){
125+
let viewportHeight = Cypress.config("viewportHeight");
126+
let viewportWidth = Cypress.config("viewportWidth");
127+
let randX = getRandomInt(curX, viewportWidth);
128+
let randY = getRandomInt(curY, viewportHeight);
129+
130+
cy.window().then((win)=>{
131+
console.log(win.document)
132+
let element = win.document.elementFromPoint(randX, randY);
133+
console.log(element)
134+
if(!!element){
135+
//Use cypress selector if any fits
136+
if(!!element.id){ //boolean that indicates if the element has a non-empty id
137+
cy.get(`#${element.id}`).rightclick();
138+
}
139+
else if(!!element.className){ //boolean that indicates if the element has a non-empty className
140+
let className = element.className.split(" ")[0];
141+
cy.get(`.${className}`).then($candidates => {
142+
//rightclick the first visible candidate
143+
for(let i = 0; i < $candidates.length; i++){
144+
let candidate = $candidates.get(i);
145+
if(!Cypress.dom.isHidden(candidate)){
146+
cy.wrap(candidate).rightclick({force:true});
147+
}
148+
}
149+
});
150+
}
151+
else{
152+
cy.get(element.tagName).then($candidates => {
153+
//rightclick the first visible candidate
154+
for(let i = 0; i < $candidates.length; i++){
155+
let candidate = $candidates.get(i);
156+
if(!Cypress.dom.isHidden(candidate)){
157+
cy.wrap(candidate).rightclick({force:true});
158+
}
159+
}
160+
});
161+
}
162+
}
163+
else{
164+
cy.get('body').rightclick(randX, randY, {force:true});
165+
}
166+
focused = !!win.document.activeElement;
167+
})
168+
}
169+
170+
function randHover(){
171+
let viewportHeight = Cypress.config("viewportHeight");
172+
let viewportWidth = Cypress.config("viewportWidth");
173+
let randX = getRandomInt(curX, viewportWidth);
174+
let randY = getRandomInt(curY, viewportHeight);
175+
176+
cy.window().then((win)=>{
177+
let element = win.document.elementFromPoint(randX, randY);
178+
if(!!element){
179+
if(element.hasAttribute('onmouseover')){
180+
//Use cypress selector if any fits
181+
if(!!element.id){ //boolean that indicates if the element has a non-empty id
182+
cy.get(`#${element.id}`).trigger('mouseover');
183+
}
184+
else if(!!element.className){ //boolean that indicates if the element has a non-empty className
185+
cy.get(`.${element.className}`).then($candidates => {
186+
//rightclick the first visible candidate
187+
for(let i = 0; i < $candidates.length; i++){
188+
let candidate = $candidates.get(i);
189+
if(!Cypress.dom.isHidden(candidate)){
190+
cy.wrap(candidate).trigger('mouseover');
191+
}
192+
}
193+
})
194+
}
195+
}
196+
}
197+
focused = !!win.document.activeElement;
198+
})
199+
}
200+
201+
function avPag(){
202+
let viewportHeight = Cypress.config("viewportHeight");
203+
curY = curY + viewportHeight;
204+
cy.scrollTo(curX, curY);
205+
}
206+
207+
function rePag(){
208+
let viewportHeight = Cypress.config("viewportHeight");
209+
curY = (viewportHeight > curY)? 0 : curY - viewportHeight;
210+
cy.scrollTo(curX, curY);
211+
}
212+
213+
function horizontalScrollFw(){
214+
let viewportWidth = Cypress.config("viewportWidth");
215+
curX = curX + viewportWidth;
216+
cy.scrollTo(curX, curY);
217+
}
218+
219+
function horizontalScrollBk(){
220+
let viewportWidth = Cypress.config("viewportWidth");
221+
curX = (viewportWidth > curX)? 0: curX - viewportWidth;
222+
cy.scrollTo(curX, curY);
223+
}
224+
225+
function reload(){
226+
cy.reload();
227+
focused = false;
228+
}
229+
230+
function enter(){
231+
if(focused){
232+
cy.focused().type("{enter}");
233+
}
234+
else{
235+
cy.get('body').type("{enter}")
236+
}
237+
}
238+
239+
function typeCharKey(){
240+
let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
241+
let type = chars.charAt(getRandomInt(0, chars.length-1));
242+
if(focused){
243+
cy.focused().type(type);
244+
}
245+
else{
246+
cy.get('body').type(type);
247+
}
248+
}
249+
250+
function spkeypress(){
251+
const specialKeys = ["{{}","{backspace}", "{del}","{downarrow}", "{end}", "{enter}", "{esc}","{home}", "{leftarrow}", "{pagedown}", "{pageup}", "{rightarrow}", "{selectall}", "{uparrow}"];
252+
const modifiers = ["{alt}", "{ctrl}", "{meta}", "{shift}", ""];
253+
let modIndex = getRandomInt(0, modifiers.length-1);
254+
let spkIndex = getRandomInt(0, specialKeys.length-1);
255+
let type = modifiers[modIndex] + specialKeys[spkIndex];
256+
if(focused){
257+
cy.focused().type(type);
258+
}
259+
else{
260+
cy.get('body').type(type);
261+
}
262+
}
263+
264+
function changeViewport(){
265+
const viewports = ["ipad-2", "ipad-mini", "iphone-3", "iphone-4", "iphone-5", "iphone-6", "iphone-6+", "iphone-x", "iphone-xr", "macbook-11", "macbook-13", "macbook-15", "samsung-note9", "samsung-s10"];
266+
let index = getRandomInt(0, viewports.length-1);
267+
const orientations = ["portrait", "landscape"];
268+
let oindex = getRandomInt(0, orientations.length-1);
269+
cy.viewport(viewports[index], orientations[oindex]);
270+
}
271+
272+
function navBack(){
273+
cy.url().then((path)=>{
274+
if(url!==path){
275+
cy.go(-1)
276+
}
277+
});
278+
}
279+
280+
function navForward(){
281+
cy.go(1)
282+
}
283+
284+
function tab(){
285+
if(focused)
286+
cy.focused().tab().focus()
287+
else
288+
cy.get('body').tab().focus()
289+
focused = true
290+
}
291+
292+
//Aggregate in a matrix-like constant
293+
const functions = [
294+
[randClick, randDClick, randRClick],
295+
[horizontalScrollBk, horizontalScrollFw, avPag, rePag],
296+
[randHover, tab],
297+
[typeCharKey],
298+
[spkeypress, enter],
299+
[reload, navBack, navForward, changeViewport]
300+
];
301+
302+
function randomEvent(){
303+
let typeIndex = getRandomInt(0, pending_events.length);
304+
if(pending_events[typeIndex] > 0){
305+
let fIndex = getRandomInt(0, functions[typeIndex].length-1);
306+
functions[typeIndex][fIndex]();
307+
pending_events[typeIndex] --;
308+
cy.wait(delay);
309+
}
310+
else{
311+
functions.splice(typeIndex, 1);
312+
pending_events.splice(typeIndex, 1);
313+
//randomEvent();
314+
}
315+
}
316+
317+
var pending_events = [,,,,,];
318+
319+
describe( `${appName} under monkeys`, function() {
320+
it(`visits ${appName} and survives monkeys`, function() {
321+
if(pct_clicks+pct_scrolls+pct_keys+pct_pgnav+pct_selectors+pct_spkeys === 100){
322+
323+
pending_events[0] = events*pct_clicks/100;
324+
pending_events[1] = events*pct_scrolls/100;
325+
pending_events[2] = events*pct_selectors/100;
326+
pending_events[3] = events*pct_keys/100;
327+
pending_events[4] = events*pct_spkeys/100;
328+
pending_events[5] = events*pct_pgnav/100;
329+
330+
cy.visit(url);
331+
cy.wait(1000);
332+
//Add an event for each type of event in order to enter the else statement of randomEvent method
333+
for(let i = 0; i < events + 5; i++){
334+
randomEvent();
335+
}
336+
}
337+
})
338+
})
339+
340+
341+
342+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
343+
//End of random monkey
344+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)