From 0a344ef8c6f8d7e3eaa68a0c581df354d5b2fc89 Mon Sep 17 00:00:00 2001 From: Malgorzata Dzienia Date: Fri, 12 Jul 2024 07:31:10 +0200 Subject: [PATCH] Monkey Tests introduces --- .../demoqaforms/helper/GremlinsHelper.java | 162 ++++++++++++++++++ .../com/capgemini/monkeyTest/MonkeyTests.java | 64 +++++++ .../src/test/resources/js/gremlins.min.js | 2 + 3 files changed, 228 insertions(+) create mode 100644 mrchecker-playwright-framework/src/main/java/com/capgemini/pages/demoqaforms/helper/GremlinsHelper.java create mode 100644 mrchecker-playwright-framework/src/test/java/com/capgemini/monkeyTest/MonkeyTests.java create mode 100644 mrchecker-playwright-framework/src/test/resources/js/gremlins.min.js diff --git a/mrchecker-playwright-framework/src/main/java/com/capgemini/pages/demoqaforms/helper/GremlinsHelper.java b/mrchecker-playwright-framework/src/main/java/com/capgemini/pages/demoqaforms/helper/GremlinsHelper.java new file mode 100644 index 00000000..8a0fa9ea --- /dev/null +++ b/mrchecker-playwright-framework/src/main/java/com/capgemini/pages/demoqaforms/helper/GremlinsHelper.java @@ -0,0 +1,162 @@ +package com.capgemini.pages.demoqaforms.helper; + +import com.microsoft.playwright.Page; +import io.qameta.allure.Allure; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * @author Michal Carlo + * @since 2024-03-19 + * Gremlins is a monkey testing library that performs random actions on the page. + */ + +public final class GremlinsHelper { + public static final String GREMLIN_JS_EXPRESSION = "gremlin JS expression"; + static final Path PATH_TO_GREMLINS = Paths.get("target/js/node_modules/gremlins.min.js"); + private static final Logger LOGGER = LoggerFactory.getLogger(GremlinsHelper.class.getCanonicalName()); + + public GremlinsHelper() { + } + + /** + * Get JS script for Gremlins. + * + * @throws IOException Gremlins script not found + */ + public static void copyGremlinsJSFromResources() throws IOException { + Files.createDirectories(Paths.get("target/js/node_modules")); + try (InputStream stream = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResourceAsStream("js/gremlins.min.js"))) { + Files.copy(stream, PATH_TO_GREMLINS); + } + } + + /** + * Install Gremlins script in the environment. + * + * @param page Playwright page + * @throws IOException Gremlins script not found + */ + public static void setupGremlinsScript( + final Page page) throws IOException { + if (!Files.exists(PATH_TO_GREMLINS)) { + copyGremlinsJSFromResources(); + } + page.evaluate( Files.readString( Path.of(System.getProperty("user.dir") + "/" + PATH_TO_GREMLINS), Charset.defaultCharset())); + } + + /** + * unleash Gremlin horde with default settings. + * + * @param page Playwright page + */ + public static void startGremlinHorde( + final Page page) { + page.evaluate("() => gremlins.createHorde().unleash()"); + } + + /** + * unleash Gremlin horde with repeatable behaviour due to overwritten seed value. + * + * @param page Playwright page + * @param randomizerValue seed value to influence gremlin behaviour + */ + public static void startGremlinHordeWithRepeatableBehaviour( + final Page page, + final int randomizerValue) { + String expression = "const horde = gremlins.createHorde({randomizer: new gremlins.Chance(%%%)})\n" + .replace("%%%", String.valueOf(randomizerValue)) + + "horde.unleash()"; + LOGGER.debug("random gremlin horde expression: {}", expression); + Allure.addAttachment(GREMLIN_JS_EXPRESSION, expression); + page.evaluate(expression); + } + + /** + * unleash Gremlin horde with a particular Gremlin number. + * + * @param page Playwright page + * @param gremlinCount number of Gremlins, tne higher, the longer the attack lasts. + */ + public static void startGremlinHordeWithGremlinCount( + final Page page, + final int gremlinCount) { + String expression = "const horde = gremlins.createHorde({ strategies: [gremlins.strategies.allTogether({ nb: %%%})],}) \n" + .replace("%%%", String.valueOf(gremlinCount)) + + "horde.unleash()"; + LOGGER.debug("gremlin count expression: {}", expression); + Allure.addAttachment(GREMLIN_JS_EXPRESSION, expression); + page.evaluate(expression); + } + + /** + * unleash Gremlin horde with particular Gremlin species. + * + * @param page Playwright page + * @param gremlinSpeciesList list of gremlin species to use, allowed values "clicker", "toucher", "formFiller", "scroller", "typer" + */ + public static void startGremlinHordeWithGremlinTypes( + final Page page, + final List gremlinSpeciesList) { + String speciesList = parseGremlinsSpeciesList(gremlinSpeciesList); + String expression = "gremlins.createHorde({\n" + + " species: %%%\n ".replace(" %%%", speciesList) + + " })\n" + + " .unleash();"; + LOGGER.debug("gremlin type expression: {}", expression); + Allure.addAttachment(GREMLIN_JS_EXPRESSION, expression); + page.evaluate(expression); + } + + /** + * unleash Gremlin horde with selectable count and species. + * + * @param page Playwright page + * @param gremlinCount number of Gremlins, tne higher, the longer the attack lasts + * @param delay delay between attacks in ms + * @param gremlinSpeciesList list of gremlin species to use, allowed values "clicker", "toucher", "formFiller", "scroller", "typer" + */ + public static void startGremlinHordeFullyCustomisable( + final Page page, + final int gremlinCount, + final int delay, + final List gremlinSpeciesList) { + String speciesList = parseGremlinsSpeciesList(gremlinSpeciesList); + String expression = "gremlins.createHorde({\n" + + " species: %%%,\n".replace(" %%%", speciesList) + + " strategies:[gremlins.strategies.allTogether({ nb: %%%})],\n".replace("%%%", String.valueOf(gremlinCount)) + + " delay: %%%,\n".replace("%%%", String.valueOf(delay)) + + " })\n" + + " .unleash();"; + LOGGER.debug("gremlin custom horde expression: {}", expression); + Allure.addAttachment(GREMLIN_JS_EXPRESSION, expression); + page.evaluate(expression); + } + + private static String parseGremlinsSpeciesList( + final List gremlinSpeciesList) { + List parsedGremlinsList = new ArrayList<>(); + for (String gremlinSpecies : gremlinSpeciesList) { + if (isSpeciesAllowed(gremlinSpecies)) { + parsedGremlinsList.add("gremlins.species." + gremlinSpecies + "()"); + } + } + return parsedGremlinsList.toString(); + } + + private static boolean isSpeciesAllowed(final String gremlinSpecies) { + List allowedSpecies = Arrays.asList("clicker", "toucher", "formFiller", "scroller", "typer"); + return allowedSpecies.contains(gremlinSpecies); + } +} diff --git a/mrchecker-playwright-framework/src/test/java/com/capgemini/monkeyTest/MonkeyTests.java b/mrchecker-playwright-framework/src/test/java/com/capgemini/monkeyTest/MonkeyTests.java new file mode 100644 index 00000000..817ed272 --- /dev/null +++ b/mrchecker-playwright-framework/src/test/java/com/capgemini/monkeyTest/MonkeyTests.java @@ -0,0 +1,64 @@ +package com.capgemini.monkeyTest; + +import com.capgemini.framework.enums.PrjEpics; +import com.capgemini.framework.logger.AllureStepLogger; +import com.capgemini.framework.logger.Logger; +import com.capgemini.framework.playwright.BaseTest; +import com.capgemini.framework.tags.Status; +import com.capgemini.pages.demoqaforms.DemoQALoginPage; +import com.capgemini.pages.demoqaforms.helper.GremlinsHelper; +import io.qameta.allure.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; + +import static com.capgemini.framework.playwright.PlaywrightFactory.getPage; + +/** + * @author Michal Carlo + * @author Malgorzata Dzienia + * @since 2024-03-19 + * Gremlins is a monkey testing library that performs random actions on the page. + */ + +@Epic(PrjEpics.DEMO_QA) +public class MonkeyTests extends BaseTest { + + private final DemoQALoginPage demoQALoginPage = new DemoQALoginPage(); + + + @Step("[SETUP]") + @BeforeEach + public void beforeEach() { + AllureStepLogger.step("This is example step inside setUpTest()"); + demoQALoginPage.startPage(); + getPage().onConsoleMessage((msg) -> { + Logger.logInfo(msg.text()); + }); + + } + @TmsLink("Test Management System ID") + @Feature("GUI") + @Description("Monkey test description") + //JUnit annotations + @Test + @Tag(Status.REVIEW) + void MonkeyTest_fill_form_test() throws IOException { + GremlinsHelper gremlinsHelper = new GremlinsHelper(); + GremlinsHelper.setupGremlinsScript(getPage()); + GremlinsHelper.startGremlinHordeWithGremlinTypes(getPage(), List.of("clicker", "formFiller", "typer")); + } + + @Test + @Tag(Status.REVIEW) + void MonkeyTest_test() throws IOException { + GremlinsHelper gremlinsHelper = new GremlinsHelper(); + GremlinsHelper.setupGremlinsScript(getPage()); + GremlinsHelper.startGremlinHorde(getPage()); + + } +} + diff --git a/mrchecker-playwright-framework/src/test/resources/js/gremlins.min.js b/mrchecker-playwright-framework/src/test/resources/js/gremlins.min.js new file mode 100644 index 00000000..733508e3 --- /dev/null +++ b/mrchecker-playwright-framework/src/test/resources/js/gremlins.min.js @@ -0,0 +1,2 @@ +!function(e,a){"object"==typeof exports&&"undefined"!=typeof module?a(exports):"function"==typeof define&&define.amd?define(["exports"],a):a((e=e||self).gremlins={})}(this,(function(e){"use strict";var a="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(e,a){return e(a={exports:{}},a.exports),a.exports}var i,r=function(e){return e&&e.Math==Math&&e},t=r("object"==typeof globalThis&&globalThis)||r("object"==typeof window&&window)||r("object"==typeof self&&self)||r("object"==typeof a&&a)||Function("return this")(),o={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},s=function(e){try{return!!e()}catch(e){return!0}},l={}.toString,c="".split,m=s((function(){return!Object("z").propertyIsEnumerable(0)}))?function(e){return"String"==function(e){return l.call(e).slice(8,-1)}(e)?c.call(e,""):Object(e)}:Object,u=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e},d=function(e){return m(u(e))},h=!s((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),p=function(e){return"object"==typeof e?null!==e:"function"==typeof e},b=t.document,g=p(b)&&p(b.createElement),C=function(e){return g?b.createElement(e):{}},f=!h&&!s((function(){return 7!=Object.defineProperty(C("div"),"a",{get:function(){return 7}}).a})),y=function(e){if(!p(e))throw TypeError(String(e)+" is not an object");return e},v=function(e,a){if(!p(e))return e;var n,i;if(a&&"function"==typeof(n=e.toString)&&!p(i=n.call(e)))return i;if("function"==typeof(n=e.valueOf)&&!p(i=n.call(e)))return i;if(!a&&"function"==typeof(n=e.toString)&&!p(i=n.call(e)))return i;throw TypeError("Can't convert object to primitive value")},A=Object.defineProperty,S={f:h?A:function(e,a,n){if(y(e),a=v(a,!0),y(n),f)try{return A(e,a,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(e[a]=n.value),e}},M=function(e,a){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:a}},T=h?function(e,a,n){return S.f(e,a,M(1,n))}:function(e,a,n){return e[a]=n,e},B=function(e,a){try{T(t,e,a)}catch(n){t[e]=a}return a},I=t["__core-js_shared__"]||B("__core-js_shared__",{}),k=n((function(e){(e.exports=function(e,a){return I[e]||(I[e]=void 0!==a?a:{})})("versions",[]).push({version:"3.6.4",mode:"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})})),P={}.hasOwnProperty,G=function(e,a){return P.call(e,a)},E=0,L=Math.random(),w=function(e){return"Symbol("+String(void 0===e?"":e)+")_"+(++E+L).toString(36)},D=!!Object.getOwnPropertySymbols&&!s((function(){return!String(Symbol())})),R=D&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,x=k("wks"),F=t.Symbol,N=R?F:F&&F.withoutSetter||w,H=function(e){return G(x,e)||(D&&G(F,e)?x[e]=F[e]:x[e]=N("Symbol."+e)),x[e]},z=Math.ceil,W=Math.floor,O=function(e){return isNaN(e=+e)?0:(e>0?W:z)(e)},_=Math.min,K=Math.max,U=Math.min,V=function(e){return function(a,n,i){var r,t,o=d(a),s=(r=o.length)>0?_(O(r),9007199254740991):0,l=function(e,a){var n=O(e);return n<0?K(n+a,0):U(n,a)}(i,s);if(e&&n!=n){for(;s>l;)if((t=o[l++])!=t)return!0}else for(;s>l;l++)if((e||l in o)&&o[l]===n)return e||l||0;return!e&&-1}},J={includes:V(!0),indexOf:V(!1)},j={},Y=J.indexOf,Z=function(e,a){var n,i=d(e),r=0,t=[];for(n in i)!G(j,n)&&G(i,n)&&t.push(n);for(;a.length>r;)G(i,n=a[r++])&&(~Y(t,n)||t.push(n));return t},q=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Q=Object.keys||function(e){return Z(e,q)},X=h?Object.defineProperties:function(e,a){y(e);for(var n,i=Q(a),r=i.length,t=0;r>t;)S.f(e,n=i[t++],a[n]);return e},$=t,ee=function(e){return"function"==typeof e?e:void 0},ae=function(e,a){return arguments.length<2?ee($[e])||ee(t[e]):$[e]&&$[e][a]||t[e]&&t[e][a]},ne=ae("document","documentElement"),ie=k("keys"),re=function(e){return ie[e]||(ie[e]=w(e))},te=re("IE_PROTO"),oe=function(){},se=function(e){return"