From 8e2febf72cc8966a88f2cc5931e26c0231b88219 Mon Sep 17 00:00:00 2001 From: JeKachan Date: Mon, 18 Jul 2022 11:35:41 +0300 Subject: [PATCH 1/4] SUIT-19005 Created openDeepLink command. --- index.d.ts | 6 +- lib/chains/openDeepLinkChain.js | 82 ++++++++++++++ suitest.js | 4 + test/chains/openDeepLinkChain.test.js | 106 ++++++++++++++++++ .../examplesTS/openDeepLinkChain.ts | 23 ++++ typeDefinition/OpenDeepLink.d.ts | 12 ++ 6 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 lib/chains/openDeepLinkChain.js create mode 100644 test/chains/openDeepLinkChain.test.js create mode 100644 testDefinition/examplesTS/openDeepLinkChain.ts create mode 100644 typeDefinition/OpenDeepLink.d.ts diff --git a/index.d.ts b/index.d.ts index c1536114..f4d995ff 100644 --- a/index.d.ts +++ b/index.d.ts @@ -40,6 +40,7 @@ import {CloseAppChain} from './typeDefinition/CloseAppChain'; import {SuspendAppChain} from './typeDefinition/SuspendAppChain'; import {RelativePosition} from './typeDefinition/RelativePositionChain'; import {LaunchMode} from './typeDefinition/constants/LaunchMode'; +import {OpenDeepLinkChain} from './typeDefinition/OpenDeepLink'; // --------------- Suitest Interface ---------------------- // @@ -90,18 +91,15 @@ declare namespace suitest { press(keys: string[], options?: { longPressMs?: string | number }): PressButtonChain; sleep(milliseconds: number): SleepChain; window(): WindowChain; - /** * @description return PromiseLike object with Buffer as value */ takeScreenshot(dataFormat?: 'raw'): TakeScreenshotChain; setScreenOrientation(orientation: ScreenOrientationValues): SetScreenOrientationChain; - /** * @description return PromiseLike object with base64 string as value */ takeScreenshot(dataFormat: 'base64'): TakeScreenshotChain; - /** * @description the complete path to the file name where the screenshot should be saved. * Can be defined as string with placeholders, for example default path @@ -116,6 +114,7 @@ declare namespace suitest { * suitest.saveScreenshot('{screenshotDir}/{dateTime}-{currentFile}-l{currentLine}.png'); */ saveScreenshot(fileName?: string): TakeScreenshotChain; + openDeepLink(deepLink: string): OpenDeepLinkChain; getPairedDevice(): null | { deviceId: string, @@ -198,6 +197,7 @@ declare namespace suitest { sleep(milliseconds: number): SleepChain; window(): WindowChain; setScreenOrientation(orientation: ScreenOrientationValues): SetScreenOrientationChain; + openDeepLink(deepLink: string): OpenDeepLinkChain; } type NetworkLogEvent = { diff --git a/lib/chains/openDeepLinkChain.js b/lib/chains/openDeepLinkChain.js new file mode 100644 index 00000000..9a3df284 --- /dev/null +++ b/lib/chains/openDeepLinkChain.js @@ -0,0 +1,82 @@ +const makeChain = require('../utils/makeChain'); +const { + abandonComposer, + makeToStringComposer, + makeThenComposer, + assertComposer, + cloneComposer, + gettersComposer, + makeToJSONComposer, +} = require('../composers'); +const {invalidInputMessage} = require('../texts'); +const {getRequestType} = require('../utils/socketChainHelper'); +const {validate, validators} = require('../validation'); + +/** + * @param {SUITEST_API} classInstance + */ +const openDeepLinkFactory = (classInstance) => { + const toJSON = (data) => ({ + type: getRequestType(data, false), + request: { + type: 'openDeepLink', + deepLink: data.deepLink, + }, + }); + + // Build composers + const toStringComposer = makeToStringComposer(toJSON); + const thenComposer = makeThenComposer(toJSON); + const toJSONComposer = makeToJSONComposer(toJSON); + + /** + * Function accepts data object of future chain as input + * and returns a list of composers that should build the chain + * @param data + * @returns {*[]} + */ + const getComposers = (data) => { + const output = [ + toStringComposer, + thenComposer, + cloneComposer, + gettersComposer, + toJSONComposer, + ]; + + if (!data.isAssert) { + output.push(assertComposer); + } + + if (!data.isAbandoned) { + output.push(abandonComposer); + } + + return output; + }; + + // Chain builder functions + const openDeepLinkChain = (deepLink) => makeChain( + classInstance, + getComposers, + { + type: 'openDeepLink', + deepLink: validate( + validators.NON_EMPTY_STRING, + deepLink, + invalidInputMessage('openDeepLink', 'Deep Link'), + ), + }, + ); + + return { + openDeepLink: openDeepLinkChain, + openDeepLinkAssert: (deepLink) => openDeepLinkChain(deepLink).toAssert(), + + // For Unit tests + getComposers, + toJSON, + }; +}; + +module.exports = openDeepLinkFactory; diff --git a/suitest.js b/suitest.js index 96d5b569..92e4507c 100644 --- a/suitest.js +++ b/suitest.js @@ -36,6 +36,7 @@ const networkRequestFactory = require('./lib/chains/networkRequestChain'); const videoFactory = require('./lib/chains/videoChain'); const playstationVideoFactory = require('./lib/chains/playstationVideoChain'); const setScreenOrientationFactory = require('./lib/chains/setScreenOrientationChain'); +const openDeepLinkFactory = require('./lib/chains/openDeepLinkChain'); // Constants const {ELEMENT_PROP, VALUE} = require('./lib/constants/element'); @@ -126,6 +127,7 @@ class SUITEST_API extends EventEmitter { const {takeScreenshot} = takeScreenshotFactory(this); const {saveScreenshot} = saveScreenshotFactory(this); const {setScreenOrientation, setScreenOrientationAssert} = setScreenOrientationFactory(this); + const {openDeepLink, openDeepLinkAssert} = openDeepLinkFactory(this); this.openApp = openApp; this.closeApp = closeApp; @@ -152,6 +154,7 @@ class SUITEST_API extends EventEmitter { this.takeScreenshot = takeScreenshot; this.saveScreenshot = saveScreenshot; this.setScreenOrientation = setScreenOrientation; + this.openDeepLink = openDeepLink; this.PROP = ELEMENT_PROP; this.COMP = PROP_COMPARATOR; @@ -198,6 +201,7 @@ class SUITEST_API extends EventEmitter { video: videoAssert, psVideo: playstationVideoAssert, setScreenOrientation: setScreenOrientationAssert, + openDeepLink: openDeepLinkAssert, }; // Listen to process events to trigger websocket termination and dump warnings, if any diff --git a/test/chains/openDeepLinkChain.test.js b/test/chains/openDeepLinkChain.test.js new file mode 100644 index 00000000..91e14141 --- /dev/null +++ b/test/chains/openDeepLinkChain.test.js @@ -0,0 +1,106 @@ +const assert = require('assert').strict; +const suitest = require('../../index'); +const {testInputErrorSync} = require('../../lib/utils/testHelpers/testInputError'); +const { + openDeepLink, + openDeepLinkAssert, + toJSON, + getComposers, +} = require('../../lib/chains/openDeepLinkChain')(suitest); +const composers = require('../../lib/constants/composer'); +const {bySymbol, getComposerTypes} = require('../../lib/utils/testHelpers'); + +describe('Open Deep Link chain', () => { + it('should have all necessary modifiers', () => { + assert.deepEqual( + getComposerTypes(getComposers({})), + [ + composers.TO_STRING, + composers.THEN, + composers.ABANDON, + composers.ASSERT, + composers.CLONE, + composers.GETTERS, + composers.TO_JSON, + ].sort(bySymbol), + 'clear state', + ); + + assert.deepEqual( + getComposerTypes(getComposers({isAbandoned: true})), + [ + composers.TO_STRING, + composers.THEN, + composers.ASSERT, + composers.CLONE, + composers.GETTERS, + composers.TO_JSON, + ].sort(bySymbol), + 'abandoned chain', + ); + + assert.deepEqual( + getComposerTypes(getComposers({isAssert: true})), + [ + composers.TO_STRING, + composers.THEN, + composers.ABANDON, + composers.CLONE, + composers.GETTERS, + composers.TO_JSON, + ].sort(bySymbol), + 'assert chain', + ); + + const chain = openDeepLink('some:deep:link'); + + assert.strictEqual(chain.with, chain); + assert.strictEqual(chain.it, chain); + assert.strictEqual(chain.should, chain); + assert.strictEqual(chain.times, chain); + }); + + it('should generate correct socket message based on data', () => { + assert.deepEqual( + toJSON({deepLink: 'deep:link'}), + { + type: 'eval', + request: { + type: 'openDeepLink', + deepLink: 'deep:link', + }, + }, + 'deep link eval json message', + ); + + assert.deepEqual( + toJSON({isAssert: true, deepLink: 'deep:link'}), + { + type: 'testLine', + request: { + type: 'openDeepLink', + deepLink: 'deep:link', + }, + }, + 'deep link assert json message', + ); + }); + + it('should throw error in case of invalid input', () => { + testInputErrorSync(openDeepLink, []); + testInputErrorSync(openDeepLink, [1]); + testInputErrorSync(openDeepLink, ['']); + testInputErrorSync(openDeepLink, [true]); + testInputErrorSync(openDeepLink, [{}]); + }); + + it('should define assert function', () => { + const chain = openDeepLinkAssert('deep:link'); + + assert.ok('toString' in chain); + assert.ok('then' in chain); + assert.ok('clone' in chain); + assert.ok('abandon' in chain); + assert.ok('toJSON' in chain); + }); +}); diff --git a/testDefinition/examplesTS/openDeepLinkChain.ts b/testDefinition/examplesTS/openDeepLinkChain.ts new file mode 100644 index 00000000..309250be --- /dev/null +++ b/testDefinition/examplesTS/openDeepLinkChain.ts @@ -0,0 +1,23 @@ +import * as suitest from '../../index'; + +const {openDeepLink} = suitest; + +// should have all necessary modifiers +const openDeepLinkChain = openDeepLink('deep:link'); + +openDeepLinkChain.toString(); +openDeepLinkChain.then(); +openDeepLinkChain.abandon(); +openDeepLinkChain.clone(); +openDeepLinkChain.toAssert(); + +// should have only toString method +const abandonedOpenDeepLink = openDeepLink('deep:link').abandon(); + +abandonedOpenDeepLink.toString(); + +// getters +openDeepLinkChain.it.should.with.times; +openDeepLinkChain.should.it.with.times; +openDeepLinkChain.with.should.it.times; +openDeepLinkChain.times.should.with.it; diff --git a/typeDefinition/OpenDeepLink.d.ts b/typeDefinition/OpenDeepLink.d.ts new file mode 100644 index 00000000..4df7e7d2 --- /dev/null +++ b/typeDefinition/OpenDeepLink.d.ts @@ -0,0 +1,12 @@ +import { + AbstractChain, + BaseChain +} from './modifiers'; + +export interface OpenDeepLinkChain extends + BaseChain +{} + +interface OpenDeepLinkAbandonedChain extends AbstractChain {} + +type OpenDeepLinkEvalResult = void | boolean; From de5b324934939d342d73f7d7e65dd824a70f492b Mon Sep 17 00:00:00 2001 From: JeKachan Date: Tue, 2 Aug 2022 17:28:29 +0300 Subject: [PATCH 2/4] SUIT-19005 allow pass empty string or no arguments to openDeepLink command. --- index.d.ts | 4 ++-- lib/chains/openDeepLinkChain.js | 26 +++++++++++++++----------- test/chains/openDeepLinkChain.test.js | 4 ++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/index.d.ts b/index.d.ts index f4d995ff..c31d5c43 100644 --- a/index.d.ts +++ b/index.d.ts @@ -114,7 +114,7 @@ declare namespace suitest { * suitest.saveScreenshot('{screenshotDir}/{dateTime}-{currentFile}-l{currentLine}.png'); */ saveScreenshot(fileName?: string): TakeScreenshotChain; - openDeepLink(deepLink: string): OpenDeepLinkChain; + openDeepLink(deepLink?: string): OpenDeepLinkChain; getPairedDevice(): null | { deviceId: string, @@ -197,7 +197,7 @@ declare namespace suitest { sleep(milliseconds: number): SleepChain; window(): WindowChain; setScreenOrientation(orientation: ScreenOrientationValues): SetScreenOrientationChain; - openDeepLink(deepLink: string): OpenDeepLinkChain; + openDeepLink(deepLink?: string): OpenDeepLinkChain; } type NetworkLogEvent = { diff --git a/lib/chains/openDeepLinkChain.js b/lib/chains/openDeepLinkChain.js index 9a3df284..157ef15b 100644 --- a/lib/chains/openDeepLinkChain.js +++ b/lib/chains/openDeepLinkChain.js @@ -56,18 +56,22 @@ const openDeepLinkFactory = (classInstance) => { }; // Chain builder functions - const openDeepLinkChain = (deepLink) => makeChain( - classInstance, - getComposers, - { - type: 'openDeepLink', - deepLink: validate( - validators.NON_EMPTY_STRING, + const openDeepLinkChain = (deepLink) => { + deepLink = deepLink === undefined ? '' : validate( + validators.STRING, + deepLink, + invalidInputMessage('openDeepLink', 'Deep Link'), + ); + + return makeChain( + classInstance, + getComposers, + { + type: 'openDeepLink', deepLink, - invalidInputMessage('openDeepLink', 'Deep Link'), - ), - }, - ); + }, + ); + }; return { openDeepLink: openDeepLinkChain, diff --git a/test/chains/openDeepLinkChain.test.js b/test/chains/openDeepLinkChain.test.js index 91e14141..d461b224 100644 --- a/test/chains/openDeepLinkChain.test.js +++ b/test/chains/openDeepLinkChain.test.js @@ -87,9 +87,9 @@ describe('Open Deep Link chain', () => { }); it('should throw error in case of invalid input', () => { - testInputErrorSync(openDeepLink, []); + testInputErrorSync(openDeepLink, [null]); testInputErrorSync(openDeepLink, [1]); - testInputErrorSync(openDeepLink, ['']); + testInputErrorSync(openDeepLink, [0]); testInputErrorSync(openDeepLink, [true]); testInputErrorSync(openDeepLink, [{}]); }); From e84c4dc85da4e128bbb81589b483483d0b38eefb Mon Sep 17 00:00:00 2001 From: JeKachan Date: Fri, 5 Aug 2022 11:25:31 +0300 Subject: [PATCH 3/4] Update @suitest/translate for adding translation for deepLink. --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d1d96e2f..b4e3af06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -448,18 +448,18 @@ } }, "@suitest/translate": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@suitest/translate/-/translate-4.5.1.tgz", - "integrity": "sha512-9r0vwcjs+yoWf4SNOIy33US101Qy/KUP/+z65kW1oUqs/bH4NqFfQnpqI8gUHFy8jwUCl24jK4D0zuFbC/72YA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@suitest/translate/-/translate-4.6.0.tgz", + "integrity": "sha512-rW/U8/sEQ6y55P3SvV5IX2nP/vT5IVvl2YLAkMpspeF6+qhpMKfdVWzEalpwuC4RDJOYrgNypFaMM1VAR1BC0g==", "requires": { "@suitest/smst": "^4.4.3", - "@suitest/types": "^4.5.1" + "@suitest/types": "^4.6.0" } }, "@suitest/types": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@suitest/types/-/types-4.5.1.tgz", - "integrity": "sha512-2G+bS4aRynjtgJ+qNORIYajLx8vmkXtqMf7cDDuRKAvd1bRUENbFWkSzGpfmhzB9R1XkGyfWWFaBEoFByTXm9Q==" + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@suitest/types/-/types-4.6.0.tgz", + "integrity": "sha512-42NRmZNZ+D+ELcnbT4oRYnq5bAtsl1OhDTfuIp5x8uVh33GcipmbZLKDxBlwVTGCTbIH9xXRN9dS2o4gfzLoGw==" }, "@types/node": { "version": "14.14.10", diff --git a/package.json b/package.json index 0783e971..4f6c8825 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ }, "dependencies": { "@suitest/smst-to-text": "^4.4.3", - "@suitest/translate": "^4.5.1", + "@suitest/translate": "^4.6.0", "@types/node": "^14.0.10", "ajv": "^6.12.2", "ansi-regex": "^5.0.0", From 1d4ab545ca8d2fe55f166948475797d56fde6c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Polomsk=C3=BD?= Date: Mon, 8 Aug 2022 09:41:45 +0200 Subject: [PATCH 4/4] 3.5.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4e3af06..c0cbb83d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "suitest-js-api", - "version": "3.4.3", + "version": "3.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4f6c8825..89d24402 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "suitest-js-api", - "version": "3.4.3", + "version": "3.5.0", "main": "index.js", "repository": "git@github.com:SuitestAutomation/suitest-js-api.git", "author": "Suitest ",