(undefined, MockBehavior.Strict);
+ depsMock
+ .setup(m => m.stepTransition('configuring-port-forwarding'))
+ .verifiable(Times.once());
+
+ const step = promptConfiguringPortForwardingFailed(depsMock.object);
+ step.actions.next();
+
+ depsMock.verifyAll();
+ });
+});
From 5d2894d368fe3d63be307b5cbc47a78ec1fa7ac2 Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Wed, 17 Jun 2020 16:17:16 -0700
Subject: [PATCH 43/71] feat(android-setup): Scan for devices without prompting
(golden path) (#2910)
---
src/electron/platform/android/setup/steps/detect-adb.ts | 2 +-
.../electron/platform/android/setup/steps/detect-adb.test.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/electron/platform/android/setup/steps/detect-adb.ts b/src/electron/platform/android/setup/steps/detect-adb.ts
index 4ba78040865..9d12823bd99 100644
--- a/src/electron/platform/android/setup/steps/detect-adb.ts
+++ b/src/electron/platform/android/setup/steps/detect-adb.ts
@@ -7,6 +7,6 @@ export const detectAdb: AndroidSetupStepConfig = deps => ({
actions: {},
onEnter: async () => {
const detected = await deps.hasAdbPath();
- deps.stepTransition(detected ? 'prompt-connect-to-device' : 'prompt-locate-adb');
+ deps.stepTransition(detected ? 'detect-devices' : 'prompt-locate-adb');
},
});
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-adb.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-adb.test.ts
index 5cfb9aacc53..e7ed34fd35a 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-adb.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-adb.test.ts
@@ -23,7 +23,7 @@ describe('Android setup step: detectAdb', () => {
.returns(_ => p)
.verifiable(Times.once());
- depsMock.setup(m => m.stepTransition('prompt-connect-to-device')).verifiable(Times.once());
+ depsMock.setup(m => m.stepTransition('detect-devices')).verifiable(Times.once());
const step = detectAdb(depsMock.object);
await step.onEnter();
From b5f4d680d4556bc4d408891c832b8a7bd3c86f94 Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Wed, 17 Jun 2020 21:36:35 -0700
Subject: [PATCH 44/71] chore(android-setup): Put
live-android-setup-deps.test.ts in the correct folder (#2912)
---
.../android/setup/{steps => }/live-android-setup-deps.test.ts | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/tests/unit/tests/electron/platform/android/setup/{steps => }/live-android-setup-deps.test.ts (100%)
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/live-android-setup-deps.test.ts b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
similarity index 100%
rename from src/tests/unit/tests/electron/platform/android/setup/steps/live-android-setup-deps.test.ts
rename to src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
From f77ae52ad09d8dd3cd25374d9736677dc5e68ddb Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 18 Jun 2020 06:16:28 +0000
Subject: [PATCH 45/71] chore(deps): bump react-resize-detector from 4.2.3 to
5.0.6 (#2897)
---
package.json | 2 +-
.../components/narrow-mode-detector.tsx | 16 +++++++++++----
.../narrow-mode-detector.test.tsx.snap | 14 ++++++++++---
.../components/narrow-mode-detector.test.tsx | 20 +++++++++++++++----
yarn.lock | 8 ++++----
5 files changed, 44 insertions(+), 16 deletions(-)
diff --git a/package.json b/package.json
index 29bb2953b08..3f5a2f51aee 100644
--- a/package.json
+++ b/package.json
@@ -156,7 +156,7 @@
"react-copy-to-clipboard": "^5.0.2",
"react-dom": "^16.13.1",
"react-helmet": "^6.1.0",
- "react-resize-detector": "^4.2.3",
+ "react-resize-detector": "^5.0.6",
"react-router-dom": "^5.2.0",
"ua-parser-js": "^0.7.21",
"uuid": "^8.1.0",
diff --git a/src/DetailsView/components/narrow-mode-detector.tsx b/src/DetailsView/components/narrow-mode-detector.tsx
index fa0d10a42c6..61a87ebeaee 100644
--- a/src/DetailsView/components/narrow-mode-detector.tsx
+++ b/src/DetailsView/components/narrow-mode-detector.tsx
@@ -4,7 +4,7 @@ import { ReactFCWithDisplayName } from 'common/react/named-fc';
import * as React from 'react';
import ReactResizeDetector from 'react-resize-detector';
-export type NarrowModeDetectorProps = {
+export type NarrowModeDetectorProps
= {
isNarrowModeEnabled: boolean;
Component: ReactFCWithDisplayName
;
childrenProps: P;
@@ -12,13 +12,21 @@ export type NarrowModeDetectorProps
= {
const NARROW_MODE_THRESHOLD_IN_PIXEL = 600;
-export function NarrowModeDetector
(props: NarrowModeDetectorProps
): JSX.Element {
- const render = (dimensions: { width: number }) => {
+export function getNarrowModeComponentWrapper
(
+ props: NarrowModeDetectorProps
,
+): (dimensions: { width: number }) => JSX.Element {
+ return (dimensions: { width: number }) => {
const isNarrowMode =
props.isNarrowModeEnabled === true && dimensions.width < NARROW_MODE_THRESHOLD_IN_PIXEL;
const childrenProps = props.childrenProps;
return ;
};
+}
- return ;
+export function NarrowModeDetector
(props: NarrowModeDetectorProps
): JSX.Element {
+ return (
+
+ {getNarrowModeComponentWrapper(props)}
+
+ );
}
diff --git a/src/tests/unit/tests/DetailsView/components/__snapshots__/narrow-mode-detector.test.tsx.snap b/src/tests/unit/tests/DetailsView/components/__snapshots__/narrow-mode-detector.test.tsx.snap
index 5ea20448b6f..79a3d5854f4 100644
--- a/src/tests/unit/tests/DetailsView/components/__snapshots__/narrow-mode-detector.test.tsx.snap
+++ b/src/tests/unit/tests/DetailsView/components/__snapshots__/narrow-mode-detector.test.tsx.snap
@@ -8,19 +8,27 @@ exports[`NarrowModeDetector render renders ReactResizeDetector 1`] = `
onResize={null}
querySelector="body"
refreshRate={1000}
- render={[Function]}
skipOnMount={false}
targetDomEl={null}
+ targetRef={null}
+>
+ [Function]
+
+`;
+
+exports[`NarrowModeDetector render renders child component properly when narrow mode is disabled: narrow mode should be false 1`] = `
+
`;
-exports[`NarrowModeDetector render renders child component properly: narrow mode should be false 1`] = `
+exports[`NarrowModeDetector render renders child component properly when narrow mode is enabled: narrow mode should be false 1`] = `
`;
-exports[`NarrowModeDetector render renders child component properly: narrow mode should be true 1`] = `
+exports[`NarrowModeDetector render renders child component properly when narrow mode is enabled: narrow mode should be true 1`] = `
diff --git a/src/tests/unit/tests/DetailsView/components/narrow-mode-detector.test.tsx b/src/tests/unit/tests/DetailsView/components/narrow-mode-detector.test.tsx
index ee7aef71b4f..1b46aaa1115 100644
--- a/src/tests/unit/tests/DetailsView/components/narrow-mode-detector.test.tsx
+++ b/src/tests/unit/tests/DetailsView/components/narrow-mode-detector.test.tsx
@@ -2,12 +2,12 @@
// Licensed under the MIT License.
import { DetailsViewContent } from 'DetailsView/components/details-view-content';
import {
+ getNarrowModeComponentWrapper,
NarrowModeDetector,
NarrowModeDetectorProps,
} from 'DetailsView/components/narrow-mode-detector';
import { shallow } from 'enzyme';
import * as React from 'react';
-import ReactResizeDetector from 'react-resize-detector';
describe(NarrowModeDetector, () => {
describe('render', () => {
@@ -21,14 +21,13 @@ describe(NarrowModeDetector, () => {
expect(wrapper.getElement()).toMatchSnapshot();
});
- it('renders child component properly', () => {
+ it('renders child component properly when narrow mode is enabled', () => {
const props: NarrowModeDetectorProps = {
isNarrowModeEnabled: true,
Component: DetailsViewContent,
childrenProps: null,
};
- const wrapper = shallow();
- const renderFunc = wrapper.find(ReactResizeDetector).props().render;
+ const renderFunc = getNarrowModeComponentWrapper(props);
expect(renderFunc({ width: 10, height: 0 })).toMatchSnapshot(
'narrow mode should be true',
@@ -37,5 +36,18 @@ describe(NarrowModeDetector, () => {
'narrow mode should be false',
);
});
+
+ it('renders child component properly when narrow mode is disabled', () => {
+ const props: NarrowModeDetectorProps = {
+ isNarrowModeEnabled: false,
+ Component: DetailsViewContent,
+ childrenProps: null,
+ };
+ const renderFunc = getNarrowModeComponentWrapper(props);
+
+ expect(renderFunc({ width: 10, height: 0 })).toMatchSnapshot(
+ 'narrow mode should be false',
+ );
+ });
});
});
diff --git a/yarn.lock b/yarn.lock
index 867f40e8db0..647c23a0b98 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8960,10 +8960,10 @@ react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-i
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
-react-resize-detector@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-4.2.3.tgz#7df258668a30bdfd88e655bbdb27db7fd7b23127"
- integrity sha512-4AeS6lxdz2KOgDZaOVt1duoDHrbYwSrUX32KeM9j6t9ISyRphoJbTRCMS1aPFxZHFqcCGLT1gMl3lEcSWZNW0A==
+react-resize-detector@^5.0.6:
+ version "5.0.6"
+ resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-5.0.6.tgz#7a5b67df1117af83249fbda8bda33df29b0b7e22"
+ integrity sha512-wvyK350xvq3GgRDd8ENE0T5wqTBniGhKuK0rGHeg0L79AlW+2Be6ulecGCzCpC6CE7Zshohf1GZyDaf2onoGFg==
dependencies:
lodash "^4.17.15"
lodash-es "^4.17.15"
From ce7c3480e95b56e45d0a1039fe104c724de3adc5 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 18 Jun 2020 16:28:37 +0000
Subject: [PATCH 46/71] chore(deps-dev): bump @types/react from 16.9.37 to
16.9.38 (#2915)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 3f5a2f51aee..aac3b57af2e 100644
--- a/package.json
+++ b/package.json
@@ -71,7 +71,7 @@
"@types/moment": "^2.13.0",
"@types/puppeteer": "^3.0.0",
"@types/q": "^1.5.4",
- "@types/react": "^16.9.37",
+ "@types/react": "^16.9.38",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-dom": "^16.9.8",
"@types/react-helmet": "^6.0.0",
diff --git a/yarn.lock b/yarn.lock
index 647c23a0b98..f3c27634e20 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1239,10 +1239,10 @@
"@types/history" "*"
"@types/react" "*"
-"@types/react@*", "@types/react@^16.9.37":
- version "16.9.37"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.37.tgz#8fb93e7dbd5b1d3796f69aa979a7fe0439bc7bea"
- integrity sha512-ZqnAXallQiZ08LTSqMfWMNvAfJEzRLOxdlbbbCIJlYGjU98BEU6bE2uBpKPGeWn+v3hIgCraHKtqUcKZBzMP/Q==
+"@types/react@*", "@types/react@^16.9.38":
+ version "16.9.38"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.38.tgz#868405dace93a4095d3e054f4c4a1de7a1ac0680"
+ integrity sha512-pHAeZbjjNRa/hxyNuLrvbxhhnKyKNiLC6I5fRF2Zr/t/S6zS41MiyzH4+c+1I9vVfvuRt1VS2Lodjr4ZWnxrdA==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"
From 7ad5657de4110aaa001359f856d792e04322b5c1 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 18 Jun 2020 16:28:43 +0000
Subject: [PATCH 47/71] chore(deps-dev): bump @types/chrome from 0.0.115 to
0.0.116 (#2917)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index aac3b57af2e..992ba7b09c4 100644
--- a/package.json
+++ b/package.json
@@ -61,7 +61,7 @@
"7zip-bin": "^5.0.3",
"@electron/get": "^1.12.2",
"@types/applicationinsights-js": "^1.0.7",
- "@types/chrome": "0.0.115",
+ "@types/chrome": "0.0.116",
"@types/enzyme": "^3.10.5",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/jest": "^26.0.0",
diff --git a/yarn.lock b/yarn.lock
index f3c27634e20..e860cab6de9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -985,10 +985,10 @@
dependencies:
"@types/node" "*"
-"@types/chrome@0.0.115":
- version "0.0.115"
- resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.115.tgz#dde40ff715a76d8c8125b0fe35287b9fdbc9f3de"
- integrity sha512-pNoYoYgGuI1/kiz53kjrXrKIjn2H8YWOI+vxVTOubX6arCHk/m/jInoyflKiP2qZHZf8+P+hh6d2y9tjaG4BPQ==
+"@types/chrome@0.0.116":
+ version "0.0.116"
+ resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.116.tgz#acb578685be2b0e9c9e0a64c15d201ccdecb1839"
+ integrity sha512-EM5AoIR1w2PtkyOMtIbQ0FAGmH4nnv28HOAVPtbNQmioc9eUMBYOe6p2BZrv9shXVV62WtyNiPi2FWS44A7BTg==
dependencies:
"@types/filesystem" "*"
"@types/har-format" "*"
From 477f7764f9329876220cc3a8da4445d977fa0608 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 18 Jun 2020 16:28:52 +0000
Subject: [PATCH 48/71] chore(deps-dev): bump simple-git from 2.7.0 to 2.7.2
(#2918)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 992ba7b09c4..f924fd689c0 100644
--- a/package.json
+++ b/package.json
@@ -121,7 +121,7 @@
"sass-loader": "^8.0.2",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
- "simple-git": "^2.7.0",
+ "simple-git": "^2.7.2",
"source-map-loader": "^1.0.0",
"spectron": "^10.0.1",
"terser-webpack-plugin": "^3.0.5",
diff --git a/yarn.lock b/yarn.lock
index e860cab6de9..de8bb2bd867 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9839,10 +9839,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-simple-git@^2.7.0:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.7.0.tgz#b555392021f5553c14530c917eae1d6f914b1672"
- integrity sha512-NpNNe0hOz3DMRWB9ewK83p/nMAkGrNO/VlWhMDaI3OdUO3UNoMv5+XlMOzO52jCyl+RZbVrIuNMpxtR4C1TQXw==
+simple-git@^2.7.2:
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.7.2.tgz#6b0de98fbdc94e22dfca5a306dc59155cff3cb40"
+ integrity sha512-SXsUw80Fppq72JI+QhfKY5d4sk8WQ2CppAcjp559OInjxYZzco7L9scsd5NwForcaQSCstNh7tsW6NnrGYfdgg==
dependencies:
"@kwsites/file-exists" "^1.1.1"
debug "^4.1.1"
From bc81321f2da0e9fb5f4caabd443ea26211db419d Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 18 Jun 2020 16:28:59 +0000
Subject: [PATCH 49/71] chore(deps-dev): bump webpack-cli from 3.3.11 to 3.3.12
(#2919)
---
package.json | 2 +-
yarn.lock | 174 +++++++++++++++++++++++----------------------------
2 files changed, 81 insertions(+), 95 deletions(-)
diff --git a/package.json b/package.json
index f924fd689c0..fac25a41c2d 100644
--- a/package.json
+++ b/package.json
@@ -134,7 +134,7 @@
"typescript": "^3.9.5",
"webdriverio": "^4.13.0",
"webpack": "^4.43.0",
- "webpack-cli": "^3.3.11",
+ "webpack-cli": "^3.3.12",
"webpack-node-externals": "^1.7.2"
},
"dependencies": {
diff --git a/yarn.lock b/yarn.lock
index de8bb2bd867..b100075aa4c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2717,15 +2717,6 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2, chalk@~2.4.1:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -2737,6 +2728,15 @@ chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2, chalk@~2.4.1:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+ dependencies:
+ ansi-styles "^3.2.1"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.3.0"
+
chalk@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
@@ -3255,17 +3255,6 @@ cross-env@^7.0.2:
dependencies:
cross-spawn "^7.0.1"
-cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
- integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
- dependencies:
- nice-try "^1.0.4"
- path-key "^2.0.1"
- semver "^5.5.0"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
cross-spawn@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
@@ -3283,6 +3272,17 @@ cross-spawn@^5.0.1:
shebang-command "^1.2.0"
which "^1.2.9"
+cross-spawn@^6.0.0, cross-spawn@^6.0.5:
+ version "6.0.5"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
+ integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
+ dependencies:
+ nice-try "^1.0.4"
+ path-key "^2.0.1"
+ semver "^5.5.0"
+ shebang-command "^1.2.0"
+ which "^1.2.9"
+
cross-spawn@^7.0.0, cross-spawn@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14"
@@ -3940,11 +3940,6 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-emojis-list@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
- integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
-
emojis-list@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
@@ -3962,19 +3957,10 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
dependencies:
once "^1.4.0"
-enhanced-resolve@4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f"
- integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==
- dependencies:
- graceful-fs "^4.1.2"
- memory-fs "^0.4.0"
- tapable "^1.0.0"
-
-enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66"
- integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==
+enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d"
+ integrity sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==
dependencies:
graceful-fs "^4.1.2"
memory-fs "^0.5.0"
@@ -4588,16 +4574,6 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"
-findup-sync@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
- integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
- dependencies:
- detect-file "^1.0.0"
- is-glob "^4.0.0"
- micromatch "^3.0.4"
- resolve-dir "^1.0.1"
-
findup-sync@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
@@ -4608,6 +4584,16 @@ findup-sync@^2.0.0:
micromatch "^3.0.4"
resolve-dir "^1.0.1"
+findup-sync@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
+ integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
+ dependencies:
+ detect-file "^1.0.0"
+ is-glob "^4.0.0"
+ micromatch "^3.0.4"
+ resolve-dir "^1.0.1"
+
findup-sync@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16"
@@ -5003,13 +4989,6 @@ global-dirs@^2.0.1:
dependencies:
ini "^1.3.5"
-global-modules@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
- integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
- dependencies:
- global-prefix "^3.0.0"
-
global-modules@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
@@ -5019,6 +4998,13 @@ global-modules@^1.0.0:
is-windows "^1.0.1"
resolve-dir "^1.0.0"
+global-modules@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
+ integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
+ dependencies:
+ global-prefix "^3.0.0"
+
global-prefix@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
@@ -5617,7 +5603,7 @@ import-lazy@^2.1.0:
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
-import-local@2.0.0:
+import-local@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==
@@ -5713,10 +5699,10 @@ inquirer@~3.3.0:
strip-ansi "^4.0.0"
through "^2.3.6"
-interpret@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
- integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
+interpret@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
+ integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
interpret@~1.1.0:
version "1.1.0"
@@ -6898,13 +6884,13 @@ loader-runner@^2.4.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
-loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
- integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
+loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
+ integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==
dependencies:
big.js "^5.2.2"
- emojis-list "^2.0.0"
+ emojis-list "^3.0.0"
json5 "^1.0.1"
loader-utils@^2.0.0:
@@ -7131,7 +7117,7 @@ memfs@^3.1.2:
dependencies:
fs-monkey "1.0.1"
-memory-fs@^0.4.0, memory-fs@^0.4.1:
+memory-fs@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
@@ -10347,13 +10333,6 @@ sumchecker@^3.0.1:
dependencies:
debug "^4.1.0"
-supports-color@6.1.0, supports-color@^6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
- integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
- dependencies:
- has-flag "^3.0.0"
-
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@@ -10373,6 +10352,13 @@ supports-color@^5.3.0, supports-color@^5.4.0:
dependencies:
has-flag "^3.0.0"
+supports-color@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
+ integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
+ dependencies:
+ has-flag "^3.0.0"
+
supports-color@^7.0.0, supports-color@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
@@ -11209,10 +11195,10 @@ uuid@^8.0.0, uuid@^8.1.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==
-v8-compile-cache@2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"
- integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==
+v8-compile-cache@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
+ integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==
v8-to-istanbul@^4.1.3:
version "4.1.3"
@@ -11352,22 +11338,22 @@ webidl-conversions@^6.0.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
-webpack-cli@^3.3.11:
- version "3.3.11"
- resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631"
- integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==
- dependencies:
- chalk "2.4.2"
- cross-spawn "6.0.5"
- enhanced-resolve "4.1.0"
- findup-sync "3.0.0"
- global-modules "2.0.0"
- import-local "2.0.0"
- interpret "1.2.0"
- loader-utils "1.2.3"
- supports-color "6.1.0"
- v8-compile-cache "2.0.3"
- yargs "13.2.4"
+webpack-cli@^3.3.12:
+ version "3.3.12"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a"
+ integrity sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==
+ dependencies:
+ chalk "^2.4.2"
+ cross-spawn "^6.0.5"
+ enhanced-resolve "^4.1.1"
+ findup-sync "^3.0.0"
+ global-modules "^2.0.0"
+ import-local "^2.0.0"
+ interpret "^1.4.0"
+ loader-utils "^1.4.0"
+ supports-color "^6.1.0"
+ v8-compile-cache "^2.1.1"
+ yargs "^13.3.2"
webpack-node-externals@^1.7.2:
version "1.7.2"
@@ -11668,7 +11654,7 @@ yargs-parser@18.x, yargs-parser@^18.1.1:
camelcase "^5.0.0"
decamelize "^1.2.0"
-yargs@13.2.4, yargs@^13.3.0, yargs@^13.3.2, yargs@^15.0.2, yargs@^15.3.1:
+yargs@^13.3.0, yargs@^13.3.2, yargs@^15.0.2, yargs@^15.3.1:
version "15.3.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b"
integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==
From 6ea005a08c145caa7cafc8f2dde4c695d5d204af Mon Sep 17 00:00:00 2001
From: Wahaj <32555133+waabid@users.noreply.github.com>
Date: Thu, 18 Jun 2020 10:57:20 -0700
Subject: [PATCH 50/71] fix: background color should extend for entire right
panel (#2901)
---
src/DetailsView/Styles/detailsview.scss | 3 +++
src/DetailsView/details-view-body.scss | 6 ++++++
src/DetailsView/details-view-body.tsx | 4 ++--
.../__snapshots__/details-view-body.test.tsx.snap | 2 +-
4 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 src/DetailsView/details-view-body.scss
diff --git a/src/DetailsView/Styles/detailsview.scss b/src/DetailsView/Styles/detailsview.scss
index 428a2bb9061..e6ac4fdc70a 100644
--- a/src/DetailsView/Styles/detailsview.scss
+++ b/src/DetailsView/Styles/detailsview.scss
@@ -193,6 +193,7 @@ div.insights-file-issue-details-dialog-container {
#details-container {
display: flex;
flex-direction: column;
+ height: 100%;
.ms-Nav-compositeLink a {
border-left: $pivotItemLeftBorderWidth $pivotItemBorderStyle $neutral-0;
@@ -244,6 +245,7 @@ div.insights-file-issue-details-dialog-container {
grid-template-rows: 1fr;
width: 100%;
min-height: 0;
+ height: 100%;
&.reflow-ui {
grid-template-columns: $detailsViewReflowLeftNavWidth 1fr;
}
@@ -439,6 +441,7 @@ div.insights-file-issue-details-dialog-container {
.details-view-body-content-pane {
display: flex;
flex-direction: column;
+ height: 100%;
&.reflow-ui {
word-break: break-word;
}
diff --git a/src/DetailsView/details-view-body.scss b/src/DetailsView/details-view-body.scss
new file mode 100644
index 00000000000..f4c1cfb50c3
--- /dev/null
+++ b/src/DetailsView/details-view-body.scss
@@ -0,0 +1,6 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+.details-view-body {
+ height: 100%;
+}
diff --git a/src/DetailsView/details-view-body.tsx b/src/DetailsView/details-view-body.tsx
index 26d5e5f721f..2b64f2e7762 100644
--- a/src/DetailsView/details-view-body.tsx
+++ b/src/DetailsView/details-view-body.tsx
@@ -8,9 +8,9 @@ import { CardsViewModel } from 'common/types/store-data/card-view-model';
import { ScanMetadata } from 'common/types/store-data/unified-data-interface';
import { DetailsViewCommandBarProps } from 'DetailsView/components/details-view-command-bar';
import { FluentSideNav, FluentSideNavDeps } from 'DetailsView/components/left-nav/fluent-side-nav';
+import * as styles from 'DetailsView/details-view-body.scss';
import { ISelection } from 'office-ui-fabric-react';
import * as React from 'react';
-
import { VisualizationConfigurationFactory } from '../common/configs/visualization-configuration-factory';
import { DropdownClickHandler } from '../common/dropdown-click-handler';
import { AssessmentStoreData } from '../common/types/store-data/assessment-result-data';
@@ -82,7 +82,7 @@ export class DetailsViewBody extends React.Component {
});
return (
-
+
{this.renderCommandBar()}
{this.renderNavBar()}
diff --git a/src/tests/unit/tests/DetailsView/__snapshots__/details-view-body.test.tsx.snap b/src/tests/unit/tests/DetailsView/__snapshots__/details-view-body.test.tsx.snap
index 405cca9b77e..a4058f9ff8b 100644
--- a/src/tests/unit/tests/DetailsView/__snapshots__/details-view-body.test.tsx.snap
+++ b/src/tests/unit/tests/DetailsView/__snapshots__/details-view-body.test.tsx.snap
@@ -2,7 +2,7 @@
exports[`DetailsViewBody render render 1`] = `
Date: Thu, 18 Jun 2020 10:57:31 -0700
Subject: [PATCH 51/71] chore: clean up ovisualization configurations (#2902)
---
.../color/visualization.tsx | 22 +++++++++----------
.../headings/visualization.tsx | 22 +++++++++----------
.../issues/visualization.tsx | 22 ++++++++++---------
.../landmarks/visualization.tsx | 22 +++++++++----------
.../tab-stops/visualization.tsx | 17 ++++++++------
src/assessments/assessment-builder.tsx | 4 +---
.../assessment-visualization-configuration.ts | 5 -----
.../assessments/assessment-builder.test.tsx | 8 +------
8 files changed, 57 insertions(+), 65 deletions(-)
diff --git a/src/ad-hoc-visualizations/color/visualization.tsx b/src/ad-hoc-visualizations/color/visualization.tsx
index d399f47bfc2..003fdc51879 100644
--- a/src/ad-hoc-visualizations/color/visualization.tsx
+++ b/src/ad-hoc-visualizations/color/visualization.tsx
@@ -9,12 +9,22 @@ import { VisualizationType } from 'common/types/visualization-type';
import { generateUID } from 'common/uid-generator';
import { adhoc as content } from 'content/adhoc';
import { AdhocStaticTestView } from 'DetailsView/components/adhoc-static-test-view';
+import { RuleAnalyzerConfiguration } from 'injected/analyzers/analyzer';
import { ScannerUtils } from 'injected/scanner-utils';
import { VisualizationInstanceProcessor } from 'injected/visualization-instance-processor';
import * as React from 'react';
const { guidance } = content.color;
+const colorRuleAnalyzerConfiguration: RuleAnalyzerConfiguration = {
+ rules: ['select-body'],
+ resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
+ telemetryProcessor: (telemetryFactory: TelemetryDataFactory) => telemetryFactory.forTestScan,
+ key: AdHocTestkeys.Color,
+ testType: VisualizationType.Color,
+ analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
+};
+
export const ColorAdHocVisualization: VisualizationConfiguration = {
getTestView: props => ,
key: AdHocTestkeys.Color,
@@ -32,17 +42,7 @@ export const ColorAdHocVisualization: VisualizationConfiguration = {
chromeCommand: '05_toggle-color',
launchPanelDisplayOrder: 5,
adhocToolsPanelDisplayOrder: 2,
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
- getAnalyzer: provider =>
- provider.createRuleAnalyzer({
- rules: ['select-body'],
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
- telemetryProcessor: (telemetryFactory: TelemetryDataFactory) =>
- telemetryFactory.forTestScan,
- key: AdHocTestkeys.Color,
- testType: VisualizationType.Color,
- analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
- }),
+ getAnalyzer: provider => provider.createRuleAnalyzer(colorRuleAnalyzerConfiguration),
getIdentifier: () => AdHocTestkeys.Color,
visualizationInstanceProcessor: () => VisualizationInstanceProcessor.nullProcessor,
getNotificationMessage: selectorMap => null,
diff --git a/src/ad-hoc-visualizations/headings/visualization.tsx b/src/ad-hoc-visualizations/headings/visualization.tsx
index 073455432c6..51c4a5532b6 100644
--- a/src/ad-hoc-visualizations/headings/visualization.tsx
+++ b/src/ad-hoc-visualizations/headings/visualization.tsx
@@ -9,6 +9,7 @@ import { VisualizationType } from 'common/types/visualization-type';
import { generateUID } from 'common/uid-generator';
import { adhoc as content } from 'content/adhoc';
import { AdhocStaticTestView } from 'DetailsView/components/adhoc-static-test-view';
+import { RuleAnalyzerConfiguration } from 'injected/analyzers/analyzer';
import { ScannerUtils } from 'injected/scanner-utils';
import { VisualizationInstanceProcessor } from 'injected/visualization-instance-processor';
import { isEmpty } from 'lodash';
@@ -16,6 +17,15 @@ import * as React from 'react';
const { guidance } = content.headings;
+const headingsRuleAnalyzerConfiguration: RuleAnalyzerConfiguration = {
+ rules: ['heading-order'],
+ resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
+ telemetryProcessor: (telemetryFactory: TelemetryDataFactory) => telemetryFactory.forTestScan,
+ key: AdHocTestkeys.Headings,
+ testType: VisualizationType.Headings,
+ analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
+};
+
export const HeadingsAdHocVisualization: VisualizationConfiguration = {
getTestView: props => ,
key: AdHocTestkeys.Headings,
@@ -33,17 +43,7 @@ export const HeadingsAdHocVisualization: VisualizationConfiguration = {
chromeCommand: '03_toggle-headings',
launchPanelDisplayOrder: 3,
adhocToolsPanelDisplayOrder: 3,
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
- getAnalyzer: provider =>
- provider.createRuleAnalyzer({
- rules: ['heading-order'],
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
- telemetryProcessor: (telemetryFactory: TelemetryDataFactory) =>
- telemetryFactory.forTestScan,
- key: AdHocTestkeys.Headings,
- testType: VisualizationType.Headings,
- analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
- }),
+ getAnalyzer: provider => provider.createRuleAnalyzer(headingsRuleAnalyzerConfiguration),
getIdentifier: () => AdHocTestkeys.Headings,
visualizationInstanceProcessor: () => VisualizationInstanceProcessor.nullProcessor,
getNotificationMessage: selectorMap => (isEmpty(selectorMap) ? 'No headings found' : null),
diff --git a/src/ad-hoc-visualizations/issues/visualization.tsx b/src/ad-hoc-visualizations/issues/visualization.tsx
index eb9d5e21406..92378060ac9 100644
--- a/src/ad-hoc-visualizations/issues/visualization.tsx
+++ b/src/ad-hoc-visualizations/issues/visualization.tsx
@@ -10,10 +10,21 @@ import { TelemetryDataFactory } from 'common/telemetry-data-factory';
import { VisualizationType } from 'common/types/visualization-type';
import { generateUID } from 'common/uid-generator';
import { AdhocIssuesTestView } from 'DetailsView/components/adhoc-issues-test-view';
+import { RuleAnalyzerConfiguration } from 'injected/analyzers/analyzer';
import { ScannerUtils } from 'injected/scanner-utils';
import { VisualizationInstanceProcessor } from 'injected/visualization-instance-processor';
import * as React from 'react';
+const issuesRuleAnalyzerConfiguration: RuleAnalyzerConfiguration = {
+ rules: null,
+ resultProcessor: (scanner: ScannerUtils) => scanner.getFailingInstances,
+ telemetryProcessor: (telemetryFactory: TelemetryDataFactory) =>
+ telemetryFactory.forIssuesAnalyzerScan,
+ key: AdHocTestkeys.Issues,
+ testType: VisualizationType.Issues,
+ analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
+};
+
export const IssuesAdHocVisualization: VisualizationConfiguration = {
key: AdHocTestkeys.Issues,
testMode: TestMode.Adhoc,
@@ -43,17 +54,8 @@ export const IssuesAdHocVisualization: VisualizationConfiguration = {
chromeCommand: '01_toggle-issues',
launchPanelDisplayOrder: 1,
adhocToolsPanelDisplayOrder: 1,
- resultProcessor: (scanner: ScannerUtils) => scanner.getFailingInstances,
getAnalyzer: provider =>
- provider.createRuleAnalyzerUnifiedScan({
- rules: null,
- resultProcessor: (scanner: ScannerUtils) => scanner.getFailingInstances,
- telemetryProcessor: (telemetryFactory: TelemetryDataFactory) =>
- telemetryFactory.forIssuesAnalyzerScan,
- key: AdHocTestkeys.Issues,
- testType: VisualizationType.Issues,
- analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
- }),
+ provider.createRuleAnalyzerUnifiedScan(issuesRuleAnalyzerConfiguration),
getIdentifier: () => AdHocTestkeys.Issues,
visualizationInstanceProcessor: () => VisualizationInstanceProcessor.nullProcessor,
getNotificationMessage: (selectorMap, key, warnings) =>
diff --git a/src/ad-hoc-visualizations/landmarks/visualization.tsx b/src/ad-hoc-visualizations/landmarks/visualization.tsx
index 937e834f7ac..483bf7aa390 100644
--- a/src/ad-hoc-visualizations/landmarks/visualization.tsx
+++ b/src/ad-hoc-visualizations/landmarks/visualization.tsx
@@ -9,6 +9,7 @@ import { VisualizationType } from 'common/types/visualization-type';
import { generateUID } from 'common/uid-generator';
import { adhoc as content } from 'content/adhoc';
import { AdhocStaticTestView } from 'DetailsView/components/adhoc-static-test-view';
+import { RuleAnalyzerConfiguration } from 'injected/analyzers/analyzer';
import { ScannerUtils } from 'injected/scanner-utils';
import { VisualizationInstanceProcessor } from 'injected/visualization-instance-processor';
import { isEmpty } from 'lodash';
@@ -16,6 +17,15 @@ import * as React from 'react';
const { guidance } = content.landmarks;
+const landmarkRuleAnalyzerConfiguration: RuleAnalyzerConfiguration = {
+ rules: ['unique-landmark'],
+ resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
+ telemetryProcessor: (telemetryFactory: TelemetryDataFactory) => telemetryFactory.forTestScan,
+ key: AdHocTestkeys.Landmarks,
+ testType: VisualizationType.Landmarks,
+ analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
+};
+
export const LandmarksAdHocVisualization: VisualizationConfiguration = {
getTestView: props => ,
key: AdHocTestkeys.Landmarks,
@@ -33,17 +43,7 @@ export const LandmarksAdHocVisualization: VisualizationConfiguration = {
chromeCommand: '02_toggle-landmarks',
launchPanelDisplayOrder: 2,
adhocToolsPanelDisplayOrder: 4,
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
- getAnalyzer: provider =>
- provider.createRuleAnalyzer({
- rules: ['unique-landmark'],
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
- telemetryProcessor: (telemetryFactory: TelemetryDataFactory) =>
- telemetryFactory.forTestScan,
- key: AdHocTestkeys.Landmarks,
- testType: VisualizationType.Landmarks,
- analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
- }),
+ getAnalyzer: provider => provider.createRuleAnalyzer(landmarkRuleAnalyzerConfiguration),
getIdentifier: () => AdHocTestkeys.Landmarks,
visualizationInstanceProcessor: () => VisualizationInstanceProcessor.nullProcessor,
getNotificationMessage: selectorMap => (isEmpty(selectorMap) ? 'No landmarks found' : null),
diff --git a/src/ad-hoc-visualizations/tab-stops/visualization.tsx b/src/ad-hoc-visualizations/tab-stops/visualization.tsx
index b4e8fafd6b3..aaee244482c 100644
--- a/src/ad-hoc-visualizations/tab-stops/visualization.tsx
+++ b/src/ad-hoc-visualizations/tab-stops/visualization.tsx
@@ -9,11 +9,20 @@ import { generateUID } from 'common/uid-generator';
import { adhoc as content } from 'content/adhoc';
import { createHowToTest } from 'content/adhoc/tabstops/how-to-test';
import { AdhocStaticTestView } from 'DetailsView/components/adhoc-static-test-view';
+import { FocusAnalyzerConfiguration } from 'injected/analyzers/analyzer';
import { VisualizationInstanceProcessor } from 'injected/visualization-instance-processor';
import * as React from 'react';
const { guidance, extraGuidance } = content.tabstops;
+const tabStopVisualizationConfiguration: FocusAnalyzerConfiguration = {
+ key: AdHocTestkeys.TabStops,
+ testType: VisualizationType.TabStops,
+ analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
+ analyzerProgressMessageType: Messages.Visualizations.TabStops.TabbedElementAdded,
+ analyzerTerminatedMessageType: Messages.Visualizations.TabStops.TerminateScan,
+};
+
export const TabStopsAdHocVisualization: VisualizationConfiguration = {
getTestView: props => (
@@ -36,13 +45,7 @@ export const TabStopsAdHocVisualization: VisualizationConfiguration = {
analyzerProgressMessageType: Messages.Visualizations.TabStops.TabbedElementAdded,
analyzerTerminatedMessageType: Messages.Visualizations.TabStops.TerminateScan,
getAnalyzer: provider =>
- provider.createFocusTrackingAnalyzer({
- key: AdHocTestkeys.TabStops,
- testType: VisualizationType.TabStops,
- analyzerMessageType: Messages.Visualizations.Common.ScanCompleted,
- analyzerProgressMessageType: Messages.Visualizations.TabStops.TabbedElementAdded,
- analyzerTerminatedMessageType: Messages.Visualizations.TabStops.TerminateScan,
- }),
+ provider.createFocusTrackingAnalyzer(tabStopVisualizationConfiguration),
getIdentifier: () => AdHocTestkeys.TabStops,
visualizationInstanceProcessor: () => VisualizationInstanceProcessor.nullProcessor,
getDrawer: provider => provider.createSVGDrawer(),
diff --git a/src/assessments/assessment-builder.tsx b/src/assessments/assessment-builder.tsx
index a01c3f3bed5..8bbf4bea2ea 100644
--- a/src/assessments/assessment-builder.tsx
+++ b/src/assessments/assessment-builder.tsx
@@ -20,7 +20,7 @@ import {
import { AssessmentTestView } from 'DetailsView/components/assessment-test-view';
import { RequirementLink } from 'DetailsView/components/requirement-link';
import { AnalyzerProvider } from 'injected/analyzers/analyzer-provider';
-import { DecoratedAxeNodeResult, ScannerUtils } from 'injected/scanner-utils';
+import { DecoratedAxeNodeResult } from 'injected/scanner-utils';
import {
PropertyBags,
VisualizationInstanceProcessor,
@@ -31,7 +31,6 @@ import { cloneDeep } from 'lodash';
import { IColumn } from 'office-ui-fabric-react';
import * as React from 'react';
import { DictionaryStringTo } from 'types/common-types';
-
import { Assessment, AssistedAssessment, ManualAssessment } from './types/iassessment';
import { ReportInstanceField } from './types/report-instance-field';
import { Requirement } from './types/requirement';
@@ -286,7 +285,6 @@ export class AssessmentBuilder {
enableTest: AssessmentBuilder.enableTest,
disableTest: AssessmentBuilder.disableTest,
getTestStatus: AssessmentBuilder.getTestStatus,
- resultProcessor: (scanner: ScannerUtils) => scanner.getAllCompletedInstances,
telemetryProcessor: factory => factory.forAssessmentRequirementScan,
...assessment.visualizationConfiguration,
key: assessment.storeDataKey,
diff --git a/src/common/configs/assessment-visualization-configuration.ts b/src/common/configs/assessment-visualization-configuration.ts
index 9a1e07c8c90..9b2866cbd92 100644
--- a/src/common/configs/assessment-visualization-configuration.ts
+++ b/src/common/configs/assessment-visualization-configuration.ts
@@ -6,14 +6,12 @@ import { ScanIncompleteWarningId } from 'common/types/scan-incomplete-warnings';
import { TestViewProps } from '../../DetailsView/components/test-view';
import { Analyzer } from '../../injected/analyzers/analyzer';
import { AnalyzerProvider } from '../../injected/analyzers/analyzer-provider';
-import { HtmlElementAxeResults, ScannerUtils } from '../../injected/scanner-utils';
import {
PropertyBags,
VisualizationInstanceProcessorCallback,
} from '../../injected/visualization-instance-processor';
import { Drawer } from '../../injected/visualization/drawer';
import { DrawerProvider } from '../../injected/visualization/drawer-provider';
-import { ScanResults } from '../../scanner/iruleresults';
import { DictionaryStringTo } from '../../types/common-types';
import { IAnalyzerTelemetryCallback } from '../types/analyzer-telemetry-callbacks';
import { AssessmentData, AssessmentStoreData } from '../types/store-data/assessment-result-data';
@@ -34,9 +32,6 @@ export interface AssessmentVisualizationConfiguration {
instanceMap?: DictionaryStringTo,
) => void;
analyzerProgressMessageType?: string;
- resultProcessor?: (
- scanner: ScannerUtils,
- ) => (results: ScanResults) => DictionaryStringTo;
telemetryProcessor?: TelemetryProcessor;
getAnalyzer: (analyzerProvider: AnalyzerProvider, testStep?: string) => Analyzer;
getIdentifier: (testStep?: string) => string;
diff --git a/src/tests/unit/tests/assessments/assessment-builder.test.tsx b/src/tests/unit/tests/assessments/assessment-builder.test.tsx
index a5ad3bf8410..527d21fb24d 100644
--- a/src/tests/unit/tests/assessments/assessment-builder.test.tsx
+++ b/src/tests/unit/tests/assessments/assessment-builder.test.tsx
@@ -24,7 +24,7 @@ import { RequirementLink } from '../../../../DetailsView/components/requirement-
import { TestViewProps } from '../../../../DetailsView/components/test-view';
import { AnalyzerConfiguration } from '../../../../injected/analyzers/analyzer';
import { AnalyzerProvider } from '../../../../injected/analyzers/analyzer-provider';
-import { DecoratedAxeNodeResult, ScannerUtils } from '../../../../injected/scanner-utils';
+import { DecoratedAxeNodeResult } from '../../../../injected/scanner-utils';
import { VisualizationInstanceProcessor } from '../../../../injected/visualization-instance-processor';
import { DrawerProvider } from '../../../../injected/visualization/drawer-provider';
@@ -179,9 +179,6 @@ describe('AssessmentBuilderTest', () => {
getDrawer: getDrawerMock.object,
switchToTargetTabOnScan: true,
};
- const scannerStub = {
- getAllCompletedInstances: {},
- };
const telemetryFactoryStub = {
forAssessmentRequirementScan: {},
};
@@ -281,9 +278,6 @@ describe('AssessmentBuilderTest', () => {
config.getDrawer(drawerProviderMock.object, requirement5.key);
expect(config.getStoreData(vizStoreData)).toEqual(scanData);
- expect(config.resultProcessor(scannerStub as ScannerUtils)).toEqual(
- scannerStub.getAllCompletedInstances,
- );
expect(config.telemetryProcessor(telemetryFactoryStub as TelemetryDataFactory)).toEqual(
telemetryFactoryStub.forAssessmentRequirementScan,
);
From 486b0dc70f58d3435457d4957f049ce7f23712c8 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 18 Jun 2020 21:07:49 +0000
Subject: [PATCH 52/71] chore(deps-dev): bump terser-webpack-plugin from 3.0.5
to 3.0.6 (#2916)
---
package.json | 2 +-
yarn.lock | 18 +++++++++---------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/package.json b/package.json
index fac25a41c2d..d305573ec77 100644
--- a/package.json
+++ b/package.json
@@ -124,7 +124,7 @@
"simple-git": "^2.7.2",
"source-map-loader": "^1.0.0",
"spectron": "^10.0.1",
- "terser-webpack-plugin": "^3.0.5",
+ "terser-webpack-plugin": "^3.0.6",
"ts-jest": "^26.1.0",
"ts-loader": "^7.0.5",
"tslint": "^5.20.1",
diff --git a/yarn.lock b/yarn.lock
index b100075aa4c..89d990ef17b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10524,10 +10524,10 @@ terser-webpack-plugin@^1.4.3:
webpack-sources "^1.4.0"
worker-farm "^1.7.0"
-terser-webpack-plugin@^3.0.5:
- version "3.0.5"
- resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.0.5.tgz#f048cfbddd6098b10a8737f3165344529656daad"
- integrity sha512-pyHUyfQUZB3ciYL81GgXzDh8Qb3fGED77xDjZVSFYSN1cQnWgC51OMPKj7vBWVZx0GGuYhpa9+Vz2KxkzXWhBA==
+terser-webpack-plugin@^3.0.6:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.0.6.tgz#db0a108bbdd3680d72c9b491fbabad09ba207b99"
+ integrity sha512-z3HLOOPUHkCNGkeEHqqiMAIy1pjpHwS1o+i6Zn0Ws3EAvHJj46737efNNEvJ0Vx9BdDQM83d56qySDJOSORA0A==
dependencies:
cacache "^15.0.4"
find-cache-dir "^3.3.1"
@@ -10536,13 +10536,13 @@ terser-webpack-plugin@^3.0.5:
schema-utils "^2.6.6"
serialize-javascript "^4.0.0"
source-map "^0.6.1"
- terser "^4.6.13"
+ terser "^4.8.0"
webpack-sources "^1.4.3"
-terser@^4.1.2, terser@^4.6.13:
- version "4.6.13"
- resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.13.tgz#e879a7364a5e0db52ba4891ecde007422c56a916"
- integrity sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==
+terser@^4.1.2, terser@^4.8.0:
+ version "4.8.0"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
+ integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==
dependencies:
commander "^2.20.0"
source-map "~0.6.1"
From 63f7ee35c3b0e9e2e0a27aff16a3685341cbe3e2 Mon Sep 17 00:00:00 2001
From: Rob Gallo <43080011+RobGallo@users.noreply.github.com>
Date: Fri, 19 Jun 2020 14:44:16 -0400
Subject: [PATCH 53/71] feat(android-setup): Add code to set the app name from
the device in the setup store (#2911)
* feat(android-setup): Add code to set the app name from the device in the setup store
The app name is required for the start testing screen, and it can't be set until after the permissions have been granted. It also can't be set in the onEnter function for the start testing step because the onEnter method is asynchronous, and the UI will therefore be visible possibly before the app name is set.
* Fix linting errors
* feat(android-setup): Modify configuringPortForwarding state machine step so that the application name is retrieved after port forwarding is successfully set up
Port forwarding, not detect permissions, is when the device is set up and ready to get the app name.
* Fix typo
Co-authored-by: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
* Update text for linguistic symmetry
Co-authored-by: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Co-authored-by: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
---
.../flux/store/android-setup-store.ts | 6 +++
.../android-setup-state-machine-types.ts | 1 +
.../flux/types/android-setup-store-data.ts | 2 +
.../android/setup/android-setup-deps.ts | 1 +
.../android/setup/live-android-setup-deps.ts | 13 +++++++
.../steps/configuring-port-forwarding.ts | 17 ++++++---
src/electron/views/renderer-initializer.ts | 5 ++-
.../flux/store/android-setup-store.test.ts | 30 +++++++++++++++
.../setup/live-android-setup-deps.test.ts | 37 +++++++++++++++++++
.../steps/configuring-port-forwarding.test.ts | 17 +++++++--
.../setup/steps/detect-permissions.test.ts | 8 ++--
11 files changed, 123 insertions(+), 14 deletions(-)
diff --git a/src/electron/flux/store/android-setup-store.ts b/src/electron/flux/store/android-setup-store.ts
index 61041931ecf..2d5feb0f4b0 100644
--- a/src/electron/flux/store/android-setup-store.ts
+++ b/src/electron/flux/store/android-setup-store.ts
@@ -28,6 +28,7 @@ export class AndroidSetupStore extends BaseStoreImpl {
stepTransition: this.stepTransition,
setSelectedDevice: this.setSelectedDevice,
setAvailableDevices: this.setAvailableDevices,
+ setApplicationName: this.setApplicationName,
});
}
@@ -67,4 +68,9 @@ export class AndroidSetupStore extends BaseStoreImpl {
// emitChange will be called from step transition when the step changes
this.state.availableDevices = devices;
};
+
+ private setApplicationName = (appName?: string): void => {
+ // emitChange will be called from step transition when the step changes
+ this.state.applicationName = appName;
+ };
}
diff --git a/src/electron/flux/types/android-setup-state-machine-types.ts b/src/electron/flux/types/android-setup-state-machine-types.ts
index a51735f4cf0..c3f9dc4d00a 100644
--- a/src/electron/flux/types/android-setup-state-machine-types.ts
+++ b/src/electron/flux/types/android-setup-state-machine-types.ts
@@ -14,6 +14,7 @@ export type AndroidSetupStoreCallbacks = {
stepTransition: AndroidSetupStepTransitionCallback;
setSelectedDevice: (device: DeviceInfo) => void;
setAvailableDevices: (devices: DeviceInfo[]) => void;
+ setApplicationName: (appName?: string) => void;
};
export type AndroidSetupStateMachineFactory = (
diff --git a/src/electron/flux/types/android-setup-store-data.ts b/src/electron/flux/types/android-setup-store-data.ts
index a2e5b15f552..a040184180e 100644
--- a/src/electron/flux/types/android-setup-store-data.ts
+++ b/src/electron/flux/types/android-setup-store-data.ts
@@ -10,4 +10,6 @@ export type AndroidSetupStoreData = {
selectedDevice?: DeviceInfo;
availableDevices?: DeviceInfo[];
+
+ applicationName?: string;
};
diff --git a/src/electron/platform/android/setup/android-setup-deps.ts b/src/electron/platform/android/setup/android-setup-deps.ts
index c557f02cc4b..c15dac47995 100644
--- a/src/electron/platform/android/setup/android-setup-deps.ts
+++ b/src/electron/platform/android/setup/android-setup-deps.ts
@@ -12,4 +12,5 @@ export type AndroidSetupDeps = {
installService: () => Promise;
hasExpectedPermissions: () => Promise;
setTcpForwarding: () => Promise;
+ getApplicationName: () => Promise;
};
diff --git a/src/electron/platform/android/setup/live-android-setup-deps.ts b/src/electron/platform/android/setup/live-android-setup-deps.ts
index ca52e52ae90..e53ed55e0ba 100644
--- a/src/electron/platform/android/setup/live-android-setup-deps.ts
+++ b/src/electron/platform/android/setup/live-android-setup-deps.ts
@@ -12,6 +12,7 @@ import {
PackageInfo,
PermissionInfo,
} from 'electron/platform/android/android-service-configurator';
+import { DeviceConfigFetcher } from 'electron/platform/android/device-config-fetcher';
import { AndroidSetupDeps } from 'electron/platform/android/setup/android-setup-deps';
export class LiveAndroidSetupDeps implements AndroidSetupDeps {
@@ -23,6 +24,7 @@ export class LiveAndroidSetupDeps implements AndroidSetupDeps {
private readonly configStore: UserConfigurationStore,
private readonly apkLocator: AndroidServiceApkLocator,
private readonly userConfigMessageCreator: UserConfigMessageCreator,
+ private readonly fetchDeviceConfig: DeviceConfigFetcher,
private readonly logger: Logger,
) {}
@@ -101,6 +103,17 @@ export class LiveAndroidSetupDeps implements AndroidSetupDeps {
return false;
};
+ public getApplicationName = async (): Promise => {
+ try {
+ const config = await this.fetchDeviceConfig(62442);
+ return config.appIdentifier;
+ } catch (error) {
+ this.logger.log(error);
+ }
+
+ return '';
+ };
+
private async getInstalledVersion(): Promise {
const info: PackageInfo = await this.serviceConfig.getPackageInfo(this.selectedDeviceId);
return info?.versionName;
diff --git a/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts b/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
index 731a0bcd8d7..ffb05968c4f 100644
--- a/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
+++ b/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
@@ -6,11 +6,18 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const configuringPortForwarding: AndroidSetupStepConfig = deps => ({
actions: {},
onEnter: async () => {
+ deps.setApplicationName(); // init
+
const configured = await deps.setTcpForwarding();
- deps.stepTransition(
- configured
- ? 'prompt-connected-start-testing'
- : 'prompt-configuring-port-forwarding-failed',
- );
+
+ if (configured === false) {
+ deps.stepTransition('prompt-configuring-port-forwarding-failed');
+ return;
+ }
+
+ // device is good to go; so we can get the current app name
+ const appName = await deps.getApplicationName();
+ deps.setApplicationName(appName);
+ deps.stepTransition('prompt-connected-start-testing');
},
});
diff --git a/src/electron/views/renderer-initializer.ts b/src/electron/views/renderer-initializer.ts
index d54133d464f..38356c0aa5b 100644
--- a/src/electron/views/renderer-initializer.ts
+++ b/src/electron/views/renderer-initializer.ts
@@ -194,9 +194,12 @@ getPersistedData(indexedDBInstance, indexedDBDataKeysToFetch).then(
const dispatcher = new DirectActionMessageDispatcher(interpreter);
const userConfigMessageCreator = new UserConfigMessageCreator(dispatcher);
+ const fetchDeviceConfig = createDeviceConfigFetcher(axios.get);
+
const apkLocator: AndroidServiceApkLocator = new AndroidServiceApkLocator(
ipcRendererShim.getAppPath,
);
+
const androidSetupStore = new AndroidSetupStore(
androidSetupActions,
createAndroidSetupStateMachineFactory(
@@ -205,6 +208,7 @@ getPersistedData(indexedDBInstance, indexedDBDataKeysToFetch).then(
userConfigurationStore,
apkLocator,
userConfigMessageCreator,
+ fetchDeviceConfig,
logger,
),
),
@@ -258,7 +262,6 @@ getPersistedData(indexedDBInstance, indexedDBDataKeysToFetch).then(
]);
const fetchScanResults = createScanResultsFetcher(axios.get);
- const fetchDeviceConfig = createDeviceConfigFetcher(axios.get);
const featureFlagsController = new FeatureFlagsController(featureFlagStore, interpreter);
diff --git a/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts b/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts
index 774fbbcebdc..014619c79ba 100644
--- a/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts
+++ b/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts
@@ -184,6 +184,36 @@ describe('AndroidSetupStore', () => {
stateMachineFactoryMock.verifyAll();
});
+ it('ensure setApplicationName function results in store update', () => {
+ const appName = 'Star Wars -- Episode Test';
+
+ const initialData: AndroidSetupStoreData = { currentStepId: 'detect-adb' };
+ const expectedData: AndroidSetupStoreData = {
+ currentStepId: 'detect-adb',
+ applicationName: appName,
+ };
+
+ let storeCallbacks: AndroidSetupStoreCallbacks;
+
+ const stateMachineFactoryMock = Mock.ofInstance(mockableStateMachineFactory);
+ stateMachineFactoryMock
+ .setup(m => m(It.isAny()))
+ .callback(sc => (storeCallbacks = sc))
+ .verifiable(Times.once());
+
+ const store = new AndroidSetupStore(
+ new AndroidSetupActions(),
+ stateMachineFactoryMock.object,
+ );
+ store.initialize(initialData);
+
+ storeCallbacks.setApplicationName(appName);
+
+ expect(store.getState()).toEqual(expectedData);
+
+ stateMachineFactoryMock.verifyAll();
+ });
+
const createAndroidSetupStoreTester = (
actionToInvoke: keyof AndroidSetupActions,
stateMachineFactory: AndroidSetupStateMachineFactory,
diff --git a/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
index a0f60a63d4c..e0ae01640c0 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
@@ -16,6 +16,8 @@ import {
PackageInfo,
PermissionInfo,
} from 'electron/platform/android/android-service-configurator';
+import { DeviceConfig } from 'electron/platform/android/device-config';
+import { DeviceConfigFetcher } from 'electron/platform/android/device-config-fetcher';
import { LiveAndroidSetupDeps } from 'electron/platform/android/setup/live-android-setup-deps';
import { IMock, Mock, MockBehavior, Times } from 'typemoq';
@@ -27,6 +29,7 @@ describe('LiveAndroidSetupDeps', () => {
let configStoreMock: IMock;
let apkLocatorMock: IMock;
let configMessageCreatorMock: IMock;
+ let fetchConfigMock: IMock;
let loggerMock: IMock;
let testSubject: LiveAndroidSetupDeps;
@@ -42,12 +45,14 @@ describe('LiveAndroidSetupDeps', () => {
undefined,
MockBehavior.Strict,
);
+ fetchConfigMock = Mock.ofInstance((port: number) => new Promise(() => null));
loggerMock = Mock.ofType();
testSubject = new LiveAndroidSetupDeps(
serviceConfigFactoryMock.object,
configStoreMock.object,
apkLocatorMock.object,
configMessageCreatorMock.object,
+ fetchConfigMock.object,
loggerMock.object,
);
});
@@ -418,6 +423,25 @@ describe('LiveAndroidSetupDeps', () => {
verifyAllMocks();
});
+ it('getApplicationName returns app name when successful', async () => {
+ const config: DeviceConfig = {
+ appIdentifier: 'Wonderful App',
+ } as DeviceConfig;
+
+ const p = new Promise(resolve => resolve(config));
+
+ fetchConfigMock
+ .setup(m => m(62442))
+ .returns(() => p)
+ .verifiable();
+
+ const appName = await testSubject.getApplicationName();
+
+ expect(appName).toEqual(config.appIdentifier);
+
+ verifyAllMocks();
+ });
+
it('setTcpForwarding returns true if no error', async () => {
serviceConfigMock.setup(m => m.setTcpForwarding(undefined)).verifiable(Times.once());
await initializeServiceConfig();
@@ -428,4 +452,17 @@ describe('LiveAndroidSetupDeps', () => {
verifyAllMocks();
});
+
+ it('getApplicationName returns empty string on error', async () => {
+ fetchConfigMock
+ .setup(m => m(62442))
+ .throws(Error('some error'))
+ .verifiable();
+
+ const appName = await testSubject.getApplicationName();
+
+ expect(appName).toEqual('');
+
+ verifyAllMocks();
+ });
});
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
index f6754b60335..41ffc02ad1c 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
@@ -15,18 +15,27 @@ describe('Android setup step: configuringPortForwarding', () => {
});
it('onEnter transitions to prompt-connected-start-testing on success', async () => {
- const p = new Promise(resolve => resolve(true));
+ const appName = 'my app name';
+
+ const tcpForwardingPromise = new Promise(resolve => resolve(true));
+ const appNamePromise = new Promise(resolve => resolve(appName));
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock
.setup(m => m.setTcpForwarding())
- .returns(_ => p)
+ .returns(_ => tcpForwardingPromise)
.verifiable(Times.once());
+ depsMock.setup(m => m.stepTransition('prompt-connected-start-testing'));
+
depsMock
- .setup(m => m.stepTransition('prompt-connected-start-testing'))
+ .setup(m => m.getApplicationName())
+ .returns(_ => appNamePromise)
.verifiable(Times.once());
+ depsMock.setup(m => m.setApplicationName(undefined)).verifiable(Times.once());
+ depsMock.setup(m => m.setApplicationName(appName)).verifiable(Times.once());
+
const step = configuringPortForwarding(depsMock.object);
await step.onEnter();
@@ -42,6 +51,8 @@ describe('Android setup step: configuringPortForwarding', () => {
.returns(_ => p)
.verifiable(Times.once());
+ depsMock.setup(m => m.setApplicationName(undefined)).verifiable(Times.once());
+
depsMock
.setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
.verifiable(Times.once());
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts
index f8d037f6c15..79b442f7c92 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts
@@ -14,7 +14,7 @@ describe('Android setup step: detectPermissions', () => {
expect(step.onEnter).toBeDefined();
});
- it('onEnter transitions to configuring-port-forwarding as expected', async () => {
+ it('onEnter transitions to configuring-port-forwarding on success', async () => {
const p = new Promise(resolve => resolve(true));
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
@@ -23,9 +23,7 @@ describe('Android setup step: detectPermissions', () => {
.returns(_ => p)
.verifiable(Times.once());
- depsMock
- .setup(m => m.stepTransition('configuring-port-forwarding'))
- .verifiable(Times.once());
+ depsMock.setup(m => m.stepTransition('configuring-port-forwarding'));
const step = detectPermissions(depsMock.object);
await step.onEnter();
@@ -33,7 +31,7 @@ describe('Android setup step: detectPermissions', () => {
depsMock.verifyAll();
});
- it('onEnter transitions to prompt-install-service as expected', async () => {
+ it('onEnter transitions to prompt-grant-permissions on failure', async () => {
const p = new Promise(resolve => resolve(false));
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
From 298e31f44ec206e0ff9152dc9c27f9f757152648 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Mon, 22 Jun 2020 15:57:49 +0000
Subject: [PATCH 54/71] chore(deps-dev): bump css-loader from 3.5.3 to 3.6.0
(#2922)
---
package.json | 2 +-
yarn.lock | 56 +++++++++++++++++++++++++++++++++-------------------
2 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/package.json b/package.json
index d305573ec77..cf5cc8e47a8 100644
--- a/package.json
+++ b/package.json
@@ -86,7 +86,7 @@
"commander": "^5.1.0",
"core-js-bundle": "^3.6.5",
"cross-env": "^7.0.2",
- "css-loader": "^3.5.3",
+ "css-loader": "^3.6.0",
"electron-builder": "^22.7.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
diff --git a/yarn.lock b/yarn.lock
index 89d990ef17b..c6979e68be8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1113,6 +1113,11 @@
"@types/parse5" "*"
"@types/tough-cookie" "*"
+"@types/json-schema@^7.0.4":
+ version "7.0.5"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
+ integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
+
"@types/lodash@^4.14.155":
version "4.14.155"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.155.tgz#e2b4514f46a261fd11542e47519c20ebce7bc23a"
@@ -1641,6 +1646,16 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
+ajv@^6.12.2:
+ version "6.12.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
+ integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
+
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
@@ -3319,23 +3334,23 @@ crypto-random-string@^2.0.0:
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
-css-loader@^3.5.3:
- version "3.5.3"
- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.3.tgz#95ac16468e1adcd95c844729e0bb167639eb0bcf"
- integrity sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw==
+css-loader@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645"
+ integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==
dependencies:
camelcase "^5.3.1"
cssesc "^3.0.0"
icss-utils "^4.1.1"
loader-utils "^1.2.3"
normalize-path "^3.0.0"
- postcss "^7.0.27"
+ postcss "^7.0.32"
postcss-modules-extract-imports "^2.0.0"
postcss-modules-local-by-default "^3.0.2"
postcss-modules-scope "^2.2.0"
postcss-modules-values "^3.0.0"
- postcss-value-parser "^4.0.3"
- schema-utils "^2.6.6"
+ postcss-value-parser "^4.1.0"
+ schema-utils "^2.7.0"
semver "^6.3.0"
css-modules-loader-core@^1.1.0:
@@ -8502,10 +8517,10 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2:
indexes-of "^1.0.1"
uniq "^1.0.1"
-postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d"
- integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==
+postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
+ integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
postcss@6.0.1:
version "6.0.1"
@@ -8525,10 +8540,10 @@ postcss@^6.0.1:
source-map "^0.6.1"
supports-color "^5.4.0"
-postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6:
- version "7.0.27"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9"
- integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==
+postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
+ version "7.0.32"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
+ integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
dependencies:
chalk "^2.4.2"
source-map "^0.6.1"
@@ -9636,12 +9651,13 @@ schema-utils@1.0.0, schema-utils@^1.0.0:
ajv-errors "^1.0.0"
ajv-keywords "^3.1.0"
-schema-utils@^2.6.1, schema-utils@^2.6.6:
- version "2.6.6"
- resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c"
- integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==
+schema-utils@^2.6.1, schema-utils@^2.6.6, schema-utils@^2.7.0:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
+ integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
dependencies:
- ajv "^6.12.0"
+ "@types/json-schema" "^7.0.4"
+ ajv "^6.12.2"
ajv-keywords "^3.4.1"
script-loader@0.7.2:
From 91d2084edf5fcd3e3a9da5282b9fba401342e169 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Mon, 22 Jun 2020 15:58:03 +0000
Subject: [PATCH 55/71] chore(deps-dev): bump fork-ts-checker-webpack-plugin
from 5.0.1 to 5.0.3 (#2923)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index cf5cc8e47a8..0e9585c9fbd 100644
--- a/package.json
+++ b/package.json
@@ -93,7 +93,7 @@
"express": "^4.16.4",
"extract-zip": "^2.0.1",
"fake-indexeddb": "^3.0.2",
- "fork-ts-checker-webpack-plugin": "^5.0.1",
+ "fork-ts-checker-webpack-plugin": "^5.0.3",
"grunt": "^1.1.0",
"grunt-bom-removal": "1.0.1",
"grunt-cli": "^1.3.1",
diff --git a/yarn.lock b/yarn.lock
index c6979e68be8..eeb1667f175 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4664,10 +4664,10 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-fork-ts-checker-webpack-plugin@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.0.1.tgz#21adab94c30340c50dc5a3d36c25d180a8bb29e5"
- integrity sha512-bys+hPwlPckrSCzNkg0BSUTsCRZWS6qIRiwk+8AjKitLWTqokda0QVImCx/Vm9cL/OGZZUnrFXazsVc99nijKQ==
+fork-ts-checker-webpack-plugin@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.0.3.tgz#8d3eba5ff022bbb0ebe895462547793c25d7fbae"
+ integrity sha512-Kp8Xa38sRfr7i8pQnGOweHzdOJRPdCIJZAkcf4T4GxzZsTMbCX4A/R+bNPdiiyYEEvIOHBALDVOeqt8CkVl+8Q==
dependencies:
"@babel/code-frame" "^7.8.3"
chalk "^2.4.1"
From f712f07d4e6a41f6cf2181090609e2ba5595e8ef Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Mon, 22 Jun 2020 15:58:12 +0000
Subject: [PATCH 56/71] chore(deps-dev): bump simple-git from 2.7.2 to 2.8.0
(#2925)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 0e9585c9fbd..aaee7bbedc9 100644
--- a/package.json
+++ b/package.json
@@ -121,7 +121,7 @@
"sass-loader": "^8.0.2",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
- "simple-git": "^2.7.2",
+ "simple-git": "^2.8.0",
"source-map-loader": "^1.0.0",
"spectron": "^10.0.1",
"terser-webpack-plugin": "^3.0.6",
diff --git a/yarn.lock b/yarn.lock
index eeb1667f175..585a9786e2c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9841,10 +9841,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-simple-git@^2.7.2:
- version "2.7.2"
- resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.7.2.tgz#6b0de98fbdc94e22dfca5a306dc59155cff3cb40"
- integrity sha512-SXsUw80Fppq72JI+QhfKY5d4sk8WQ2CppAcjp559OInjxYZzco7L9scsd5NwForcaQSCstNh7tsW6NnrGYfdgg==
+simple-git@^2.8.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.8.0.tgz#c8ebda4a16b57c9f774a62df62cb74cfd2c4f3d5"
+ integrity sha512-0iXwizUaanqdjn9IpboozWN2opA7jl1JZzeQEePyFXRUGOtwVuSgkMGXLnd7Toa7jqV+uZ1VnDZlCBxxSEk1Dw==
dependencies:
"@kwsites/file-exists" "^1.1.1"
debug "^4.1.1"
From a47e56290219b73630288f861d98f7524925c844 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Mon, 22 Jun 2020 16:48:49 +0000
Subject: [PATCH 57/71] chore(deps): bump moment from 2.26.0 to 2.27.0 (#2924)
---
package.json | 2 +-
src/packages/accessibility-insights-ui/root/package.json | 2 +-
src/reports/package/root/package.json | 2 +-
yarn.lock | 8 ++++----
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/package.json b/package.json
index aaee7bbedc9..973b44fd83a 100644
--- a/package.json
+++ b/package.json
@@ -149,7 +149,7 @@
"electron-updater": "^4.3.1",
"idb-keyval": "^3.2.0",
"lodash": "^4.17.15",
- "moment": "^2.26.0",
+ "moment": "^2.27.0",
"office-ui-fabric-react": "7.98.0",
"q": "1.5.1",
"react": "^16.13.1",
diff --git a/src/packages/accessibility-insights-ui/root/package.json b/src/packages/accessibility-insights-ui/root/package.json
index 88617cbca95..71cd86a9b00 100644
--- a/src/packages/accessibility-insights-ui/root/package.json
+++ b/src/packages/accessibility-insights-ui/root/package.json
@@ -11,7 +11,7 @@
"axe-core": "3.3.2",
"classnames": "^2.2.6",
"lodash": "^4.17.15",
- "moment": "^2.26.0",
+ "moment": "^2.27.0",
"office-ui-fabric-react": "7.98.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
diff --git a/src/reports/package/root/package.json b/src/reports/package/root/package.json
index a68451d5a8a..fcedd77a0c2 100644
--- a/src/reports/package/root/package.json
+++ b/src/reports/package/root/package.json
@@ -11,7 +11,7 @@
"axe-core": "3.5.1",
"classnames": "^2.2.6",
"lodash": "^4.17.15",
- "moment": "^2.26.0",
+ "moment": "^2.27.0",
"office-ui-fabric-react": "7.98.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
diff --git a/yarn.lock b/yarn.lock
index 585a9786e2c..bbef68c981d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7410,10 +7410,10 @@ mkdirp@1.x, mkdirp@^1.0.0, mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.3:
dependencies:
minimist "^1.2.5"
-moment@*, moment@^2.24.0, moment@^2.26.0:
- version "2.26.0"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
- integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==
+moment@*, moment@^2.24.0, moment@^2.27.0:
+ version "2.27.0"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
+ integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
moo@^0.4.3:
version "0.4.3"
From 4a67a315461fdca3c0c8702c859cdaa43b811c3f Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Mon, 22 Jun 2020 09:50:18 -0700
Subject: [PATCH 58/71] fix(android-setup): Display the current application in
the "connected" dialog (#2930)
---
.../android-setup/prompt-connected-start-testing-step.tsx | 1 +
.../prompt-connected-start-testing-step.test.tsx.snap | 2 ++
.../android-setup/prompt-connected-start-testing-step.test.tsx | 3 +++
3 files changed, 6 insertions(+)
diff --git a/src/electron/views/device-connect-view/components/android-setup/prompt-connected-start-testing-step.tsx b/src/electron/views/device-connect-view/components/android-setup/prompt-connected-start-testing-step.tsx
index 99cac8a7f50..b13c324c398 100644
--- a/src/electron/views/device-connect-view/components/android-setup/prompt-connected-start-testing-step.tsx
+++ b/src/electron/views/device-connect-view/components/android-setup/prompt-connected-start-testing-step.tsx
@@ -38,6 +38,7 @@ export const PromptConnectedStartTestingStep = NamedFC
{
+ const testApp: string = 'super-cool app';
let props: CommonAndroidSetupStepProps;
let startTestingMock: IMock;
let androidSetupActionCreatorMock: IMock;
@@ -33,6 +34,7 @@ describe('PromptConnectedStartTestingStep', () => {
};
props.androidSetupStoreData.selectedDevice = selectedDevice;
+ props.androidSetupStoreData.applicationName = testApp;
const rendered = shallow();
expect(rendered.getElement()).toMatchSnapshot();
@@ -46,6 +48,7 @@ describe('PromptConnectedStartTestingStep', () => {
};
props.androidSetupStoreData.selectedDevice = selectedDevice;
+ props.androidSetupStoreData.applicationName = testApp;
const rendered = shallow();
expect(rendered.getElement()).toMatchSnapshot();
From 84a9cf0a5b0eb48d142fd419af29b7916908f3bb Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Mon, 22 Jun 2020 10:29:57 -0700
Subject: [PATCH 59/71] (chore): Exclude .vs folder from fastpass scans (#2928)
---
.prettierignore | 1 +
copyright-header.config.json | 1 +
2 files changed, 2 insertions(+)
diff --git a/.prettierignore b/.prettierignore
index 5d79e8f0f2c..9336ffc4ac4 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -17,6 +17,7 @@
.github/
.prettierignore
.yarnrc
+.vs/
AppXManifest.xml
copyright-header.txt
dist/
diff --git a/copyright-header.config.json b/copyright-header.config.json
index 50e7e80b008..c21b269cd7c 100644
--- a/copyright-header.config.json
+++ b/copyright-header.config.json
@@ -4,6 +4,7 @@
"./.dependabot",
"./.git",
"./.github",
+ "./.vs",
"./.vscode",
"./dist",
"./docs/art/ada-cat.ansi256.txt",
From 3e2824de1dda541eb70fbc5b5f22c09214b7ddd1 Mon Sep 17 00:00:00 2001
From: Dan Bjorge
Date: Mon, 22 Jun 2020 10:30:02 -0700
Subject: [PATCH 60/71] Add scss:build step to fastpass (#2931)
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 973b44fd83a..edbb1c65ea1 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
"copyright:check": "license-check-and-add check -f copyright-header.config.json",
"copyright:fix": "license-check-and-add add -f copyright-header.config.json",
"download:electron-mirror": "node ./pipeline/scripts/download-electron-mirror.js",
- "fastpass": "npm-run-all --print-label --parallel copyright:check lint:check format:check null:check && grunt ada-cat",
+ "fastpass": "npm-run-all --print-label scss:build --parallel copyright:check lint:check format:check null:check && grunt ada-cat",
"fastpass:fix": "npm-run-all --print-label --serial scss:clean copyright:fix lint:fix format:fix",
"format:check": "prettier --config prettier.config.js --check \"**/*\"",
"format:fix": "prettier --config prettier.config.js --write \"**/*\"",
From 6bad71b67b2ae9b3bd35458465efc3a11bbe1bd4 Mon Sep 17 00:00:00 2001
From: Rob Gallo <43080011+RobGallo@users.noreply.github.com>
Date: Mon, 22 Jun 2020 13:40:34 -0400
Subject: [PATCH 61/71] feat(android-setup): Add cancel action behavior to a
few steps (#2929)
* feat(android-setup): Add cancel action behavior to a few steps
The expected behavior of the cancel action for each step is as follows:
step | on cancel
--- | ---
detect-adb | no cancel / cancel = close
prompt-locate-adb | no cancel / cancel = close
prompt-connect-to-device | no cancel / cancel = close
detect-devices | prompt-connect-to-device
prompt-choose-device | no cancel (can rescan for devices or close)
detect-service | prompt-choose-device
prompt-install-service | prompt-choose-device
installing-service | prompt-install-service
prompt-install-failed | prompt-choose-device
detect-permissions | prompt-choose-device
prompt-grant-permissions | prompt-choose-device
configuring-port-forwarding | prompt-choose-device
prompt-configuring-port-forwarding-failed | prompt-choose-device
prompt-connected-start-testing | no cancel (can rescan for devices or close)
* Remove cancel actions for detect-* state machine steps
These operations can't be canceled because we have no way to interrupt the calls -- we're awaiting promises.
* Remove cancel action from configuring-port-forwarding state machine step
There's no way to cancel the action of the step.
---
.../platform/android/setup/steps/detect-devices.ts | 7 ++-----
.../prompt-configuring-port-forwarding-failed.ts | 3 +++
.../android/setup/steps/prompt-grant-permissions.ts | 3 +++
.../android/setup/steps/prompt-install-service.ts | 3 +++
.../android/setup/steps/detect-devices.test.ts | 13 ++-----------
...rompt-configuring-port-forwarding-failed.test.ts | 12 +++++++++++-
.../setup/steps/prompt-grant-permissions.test.ts | 12 +++++++++++-
.../setup/steps/prompt-install-service.test.ts | 12 +++++++++++-
8 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/src/electron/platform/android/setup/steps/detect-devices.ts b/src/electron/platform/android/setup/steps/detect-devices.ts
index 0cee5a9e977..76a4bcbaa79 100644
--- a/src/electron/platform/android/setup/steps/detect-devices.ts
+++ b/src/electron/platform/android/setup/steps/detect-devices.ts
@@ -5,11 +5,7 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const detectDevices: AndroidSetupStepConfig = deps => {
return {
- actions: {
- cancel: () => {
- deps.stepTransition('prompt-connect-to-device');
- },
- },
+ actions: {},
onEnter: async () => {
deps.setSelectedDevice(null);
deps.setAvailableDevices([]);
@@ -24,6 +20,7 @@ export const detectDevices: AndroidSetupStepConfig = deps => {
case 1: {
deps.setSelectedDeviceId(devices[0].id);
deps.setSelectedDevice(devices[0]);
+ deps.setAvailableDevices(devices);
deps.stepTransition('detect-service');
break;
}
diff --git a/src/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.ts b/src/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.ts
index ea68bbe9a1d..760a5383e5b 100644
--- a/src/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.ts
+++ b/src/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.ts
@@ -6,6 +6,9 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const promptConfiguringPortForwardingFailed: AndroidSetupStepConfig = deps => {
return {
actions: {
+ cancel: () => {
+ deps.stepTransition('prompt-choose-device');
+ },
next: () => deps.stepTransition('configuring-port-forwarding'),
},
};
diff --git a/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts b/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts
index 5492e7b4236..7e2b856ec41 100644
--- a/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts
+++ b/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts
@@ -5,6 +5,9 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const promptGrantPermissions: AndroidSetupStepConfig = deps => ({
actions: {
+ cancel: () => {
+ deps.stepTransition('prompt-choose-device');
+ },
next: () => {
deps.stepTransition('detect-permissions');
},
diff --git a/src/electron/platform/android/setup/steps/prompt-install-service.ts b/src/electron/platform/android/setup/steps/prompt-install-service.ts
index 3ca14c665cb..16d4e52c26f 100644
--- a/src/electron/platform/android/setup/steps/prompt-install-service.ts
+++ b/src/electron/platform/android/setup/steps/prompt-install-service.ts
@@ -5,6 +5,9 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const promptInstallService: AndroidSetupStepConfig = deps => ({
actions: {
+ cancel: () => {
+ deps.stepTransition('prompt-choose-device');
+ },
next: () => {
deps.stepTransition('installing-service');
},
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-devices.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-devices.test.ts
index b4096fb08db..f0e16547519 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-devices.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-devices.test.ts
@@ -11,20 +11,10 @@ describe('Android setup step: detectDevices', () => {
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = detectDevices(deps);
- checkExpectedActionsAreDefined(step, ['cancel']);
+ checkExpectedActionsAreDefined(step, []);
expect(step.onEnter).toBeDefined();
});
- it('cancel transitions to prompt-connect-to-device as expected', () => {
- const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
- depsMock.setup(m => m.stepTransition('prompt-connect-to-device')).verifiable(Times.once());
-
- const step = detectDevices(depsMock.object);
- step.actions.cancel();
-
- depsMock.verifyAll();
- });
-
it('onEnter transitions to prompt-connect-to-device as expected', async () => {
const devices: DeviceInfo[] = [];
const p = new Promise(resolve => resolve(devices));
@@ -64,6 +54,7 @@ describe('Android setup step: detectDevices', () => {
depsMock.setup(m => m.setAvailableDevices([])).verifiable(Times.once());
depsMock.setup(m => m.setSelectedDeviceId('device1')).verifiable(Times.once());
depsMock.setup(m => m.setSelectedDevice(devices[0])).verifiable(Times.once());
+ depsMock.setup(m => m.setAvailableDevices(devices)).verifiable(Times.once());
depsMock.setup(m => m.stepTransition('detect-service')).verifiable(Times.once());
const step = detectDevices(depsMock.object);
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.test.ts
index 8c8b038d876..a101d94689d 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed.test.ts
@@ -10,10 +10,20 @@ describe('Android setup step: promptConfiguringPortForwardingFailed', () => {
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = promptConfiguringPortForwardingFailed(deps);
- checkExpectedActionsAreDefined(step, ['next']);
+ checkExpectedActionsAreDefined(step, ['cancel', 'next']);
expect(step.onEnter).not.toBeDefined();
});
+ it('cancel transitions to prompt-choose-device', async () => {
+ const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
+ depsMock.setup(m => m.stepTransition('prompt-choose-device')).verifiable(Times.once());
+
+ const step = promptConfiguringPortForwardingFailed(depsMock.object);
+ step.actions.cancel();
+
+ depsMock.verifyAll();
+ });
+
it('next transitions to configuring-port-forwarding as expected', () => {
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts
index a65ce6101d8..9649b74939b 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts
@@ -10,10 +10,20 @@ describe('Android setup step: promptGrantPermissions', () => {
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = promptGrantPermissions(deps);
- checkExpectedActionsAreDefined(step, ['next']);
+ checkExpectedActionsAreDefined(step, ['cancel', 'next']);
expect(step.onEnter).not.toBeDefined();
});
+ it('cancel transitions to prompt-choose-device', async () => {
+ const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
+ depsMock.setup(m => m.stepTransition('prompt-choose-device')).verifiable(Times.once());
+
+ const step = promptGrantPermissions(depsMock.object);
+ step.actions.cancel();
+
+ depsMock.verifyAll();
+ });
+
it('onEnter transitions to detect-permissions as expected', () => {
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock.setup(m => m.stepTransition('detect-permissions')).verifiable(Times.once());
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts
index aeca3c235b2..9dbe52f4d41 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts
@@ -10,10 +10,20 @@ describe('Android setup step: promptInstallService', () => {
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = promptInstallService(deps);
- checkExpectedActionsAreDefined(step, ['next']);
+ checkExpectedActionsAreDefined(step, ['cancel', 'next']);
expect(step.onEnter).not.toBeDefined();
});
+ it('cancel transitions to prompt-choose-device', async () => {
+ const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
+ depsMock.setup(m => m.stepTransition('prompt-choose-device')).verifiable(Times.once());
+
+ const step = promptInstallService(depsMock.object);
+ step.actions.cancel();
+
+ depsMock.verifyAll();
+ });
+
it('onEnter transitions to installing-service as expected', () => {
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock.setup(m => m.stepTransition('installing-service')).verifiable(Times.once());
From f25edfd348d68678ba8e66869a0b48a63b79fcb6 Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Mon, 22 Jun 2020 13:03:34 -0700
Subject: [PATCH 62/71] fix(android-setup): Enable "choose device" dialog on
cancel, use real data (#2932)
---
.../setup/android-setup-steps-configs.ts | 2 +-
.../prompt-choose-device-step.tsx | 20 +-----------------
.../prompt-choose-device-step.test.tsx | 21 +++++++++++++++++++
3 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/src/electron/platform/android/setup/android-setup-steps-configs.ts b/src/electron/platform/android/setup/android-setup-steps-configs.ts
index 3b3f2eb123e..06965263f49 100644
--- a/src/electron/platform/android/setup/android-setup-steps-configs.ts
+++ b/src/electron/platform/android/setup/android-setup-steps-configs.ts
@@ -40,7 +40,7 @@ export const allAndroidSetupStepConfigs: AndroidSetupStepConfigs = {
'prompt-locate-adb': promptLocateAdb,
'prompt-connect-to-device': promptConnectToDevice,
'detect-devices': detectDevices,
- 'prompt-choose-device': null,
+ 'prompt-choose-device': promptConnectToDevice,
'detect-service': detectService,
'prompt-install-service': promptInstallService,
'installing-service': installingService,
diff --git a/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx b/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx
index dfdbfdb4042..e6c75f7c7eb 100644
--- a/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx
+++ b/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx
@@ -40,25 +40,7 @@ export class PromptChooseDeviceStep extends React.Component<
}
public render(): JSX.Element {
- // Available devices will be retrieved from store in future feature work
- const devices: DeviceInfo[] = [
- {
- id: '1',
- friendlyName: 'Phone 1',
- isEmulator: true,
- },
- {
- id: '2',
- friendlyName: 'Phone 2',
- isEmulator: false,
- },
- {
- id: '3',
- friendlyName: 'Phone 3',
- isEmulator: true,
- },
- ];
-
+ const devices: DeviceInfo[] = this.props.androidSetupStoreData.availableDevices;
const items = devices.map(m => ({ metadata: m }));
const layoutProps: AndroidSetupStepLayoutProps = {
diff --git a/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx b/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx
index a0f8f08f019..4f656b6010d 100644
--- a/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx
+++ b/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { AndroidSetupActionCreator } from 'electron/flux/action-creator/android-setup-action-creator';
+import { AndroidSetupStoreData } from 'electron/flux/types/android-setup-store-data';
import { AndroidSetupStepLayout } from 'electron/views/device-connect-view/components/android-setup/android-setup-step-layout';
import { CommonAndroidSetupStepProps } from 'electron/views/device-connect-view/components/android-setup/android-setup-types';
import { PromptChooseDeviceStep } from 'electron/views/device-connect-view/components/android-setup/prompt-choose-device-step';
@@ -21,6 +22,26 @@ describe('PromptChooseDeviceStep', () => {
.withDep('closeApp', closeAppMock.object)
.withDep('androidSetupActionCreator', actionMessageCreatorMock.object)
.build();
+
+ props.androidSetupStoreData = {
+ availableDevices: [
+ {
+ id: '1',
+ friendlyName: 'Phone 1',
+ isEmulator: true,
+ },
+ {
+ id: '2',
+ friendlyName: 'Phone 2',
+ isEmulator: false,
+ },
+ {
+ id: '3',
+ friendlyName: 'Phone 3',
+ isEmulator: true,
+ },
+ ],
+ } as AndroidSetupStoreData;
});
it('renders per snapshot', () => {
From 2910c9b8bd94ed783553996d7b31d03158ef5c65 Mon Sep 17 00:00:00 2001
From: Dan Bjorge
Date: Mon, 22 Jun 2020 13:40:31 -0700
Subject: [PATCH 63/71] refactor: route scanPort through android setup store
(#2913)
#### Description of changes
This PR adds `scanPort` to `AndroidSetupStoreData`, sets up the `configuring-port-forwarding` step to set the new state, and configures the views that consume it to conditionally pick up the scan port from whichever of `AndroidSetupStore` or `DeviceStore` the `adbSetupView` feature flag says is canonical.
This PR is setup work for both:
* Removing the DeviceStore when we remove the feature flag
* Enabling dynamic port selection
Verified no functionality/UI change either with or without the adbSetupView flag
#### Pull request checklist
- [n/a] Addresses an existing issue: #0000
- [x] Ran `yarn fastpass`
- [x] Added/updated relevant unit test(s) (and ran `yarn test`)
- [x] Verified code coverage for the changes made. Check coverage report at: `/test-results/unit/coverage`
- [x] PR title *AND* final merge commit title both start with a semantic tag (`fix:`, `chore:`, `feat(feature-name):`, `refactor:`). See `CONTRIBUTING.md`.
- [n/a] (UI changes only) Added screenshots/GIFs to description above
- [n/a] (UI changes only) Verified usability with NVDA/JAWS
---
.../flux/store/android-setup-store.ts | 6 +
src/electron/flux/store/device-store.ts | 3 +-
.../android-setup-state-machine-types.ts | 1 +
.../flux/types/android-setup-store-data.ts | 2 +-
.../android/android-service-configurator.ts | 2 +-
.../android/appium-service-configurator.ts | 3 +-
.../android/setup/android-setup-deps.ts | 4 +-
.../android/setup/live-android-setup-deps.ts | 12 +-
.../steps/configuring-port-forwarding.ts | 21 +-
.../automated-checks-view.tsx | 25 +-
.../components/command-bar.tsx | 7 +-
.../flux/store/android-setup-store.test.ts | 30 ++
.../appium-service-configurator.test.ts | 3 +-
.../setup/live-android-setup-deps.test.ts | 30 +-
.../steps/configuring-port-forwarding.test.ts | 105 +++-
.../automated-checks-view.test.tsx.snap | 491 +++++++++++++++++-
.../automated-checks-view.test.tsx | 366 ++++++++-----
.../components/command-bar.test.tsx | 4 +-
18 files changed, 901 insertions(+), 214 deletions(-)
diff --git a/src/electron/flux/store/android-setup-store.ts b/src/electron/flux/store/android-setup-store.ts
index 2d5feb0f4b0..4a076a74d1e 100644
--- a/src/electron/flux/store/android-setup-store.ts
+++ b/src/electron/flux/store/android-setup-store.ts
@@ -28,6 +28,7 @@ export class AndroidSetupStore extends BaseStoreImpl {
stepTransition: this.stepTransition,
setSelectedDevice: this.setSelectedDevice,
setAvailableDevices: this.setAvailableDevices,
+ setScanPort: this.setScanPort,
setApplicationName: this.setApplicationName,
});
}
@@ -69,6 +70,11 @@ export class AndroidSetupStore extends BaseStoreImpl {
this.state.availableDevices = devices;
};
+ private setScanPort = (scanPort?: number): void => {
+ // emitChange will be called from step transition when the step changes
+ this.state.scanPort = scanPort;
+ };
+
private setApplicationName = (appName?: string): void => {
// emitChange will be called from step transition when the step changes
this.state.applicationName = appName;
diff --git a/src/electron/flux/store/device-store.ts b/src/electron/flux/store/device-store.ts
index ce8d774e0bf..71b293a6bca 100644
--- a/src/electron/flux/store/device-store.ts
+++ b/src/electron/flux/store/device-store.ts
@@ -3,7 +3,6 @@
import { BaseStoreImpl } from 'background/stores/base-store-impl';
import { StoreNames } from 'common/stores/store-names';
-import { defaultAdbPortNumber } from 'electron/platform/android/appium-service-configurator';
import { ConnectedDevicePayload, PortPayload } from '../action/device-action-payloads';
import { DeviceActions } from '../action/device-actions';
import { DeviceConnectState } from '../types/device-connect-state';
@@ -18,7 +17,7 @@ export class DeviceStore extends BaseStoreImpl {
return {
deviceConnectState: DeviceConnectState.Default,
connectedDevice: null,
- port: defaultAdbPortNumber,
+ port: null,
};
}
diff --git a/src/electron/flux/types/android-setup-state-machine-types.ts b/src/electron/flux/types/android-setup-state-machine-types.ts
index c3f9dc4d00a..b0df58a14fb 100644
--- a/src/electron/flux/types/android-setup-state-machine-types.ts
+++ b/src/electron/flux/types/android-setup-state-machine-types.ts
@@ -14,6 +14,7 @@ export type AndroidSetupStoreCallbacks = {
stepTransition: AndroidSetupStepTransitionCallback;
setSelectedDevice: (device: DeviceInfo) => void;
setAvailableDevices: (devices: DeviceInfo[]) => void;
+ setScanPort: (scanPort?: number) => void;
setApplicationName: (appName?: string) => void;
};
diff --git a/src/electron/flux/types/android-setup-store-data.ts b/src/electron/flux/types/android-setup-store-data.ts
index a040184180e..9ba2d8bf759 100644
--- a/src/electron/flux/types/android-setup-store-data.ts
+++ b/src/electron/flux/types/android-setup-store-data.ts
@@ -8,8 +8,8 @@ export type AndroidSetupStoreData = {
// undefined if no device exists or if no device has been selected
selectedDevice?: DeviceInfo;
-
availableDevices?: DeviceInfo[];
+ scanPort?: number;
applicationName?: string;
};
diff --git a/src/electron/platform/android/android-service-configurator.ts b/src/electron/platform/android/android-service-configurator.ts
index bc2b727969a..4659cb2fef1 100644
--- a/src/electron/platform/android/android-service-configurator.ts
+++ b/src/electron/platform/android/android-service-configurator.ts
@@ -22,7 +22,7 @@ export interface AndroidServiceConfigurator {
getPermissionInfo(deviceId: string): Promise;
installService(deviceId: string): Promise;
uninstallService(deviceId: string): Promise;
- setTcpForwarding(deviceId: string): Promise;
+ setTcpForwarding(deviceId: string): Promise;
removeTcpForwarding(deviceId: string): Promise;
}
diff --git a/src/electron/platform/android/appium-service-configurator.ts b/src/electron/platform/android/appium-service-configurator.ts
index 1f8e333a344..ef2c6dee1e1 100644
--- a/src/electron/platform/android/appium-service-configurator.ts
+++ b/src/electron/platform/android/appium-service-configurator.ts
@@ -82,9 +82,10 @@ export class AppiumServiceConfigurator implements AndroidServiceConfigurator {
await this.adb.uninstallApk(servicePackageName);
};
- public setTcpForwarding = async (deviceId: string): Promise => {
+ public setTcpForwarding = async (deviceId: string): Promise => {
this.adb.setDeviceId(deviceId);
await this.adb.forwardPort(defaultAdbPortNumber, defaultAdbPortNumber);
+ return defaultAdbPortNumber;
};
public removeTcpForwarding = async (deviceId: string): Promise => {
diff --git a/src/electron/platform/android/setup/android-setup-deps.ts b/src/electron/platform/android/setup/android-setup-deps.ts
index c15dac47995..dc105537238 100644
--- a/src/electron/platform/android/setup/android-setup-deps.ts
+++ b/src/electron/platform/android/setup/android-setup-deps.ts
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+import { Logger } from 'common/logging/logger';
import { DeviceInfo } from 'electron/platform/android/android-service-configurator';
export type AndroidSetupDeps = {
@@ -11,6 +12,7 @@ export type AndroidSetupDeps = {
hasExpectedServiceVersion: () => Promise;
installService: () => Promise;
hasExpectedPermissions: () => Promise;
- setTcpForwarding: () => Promise;
+ setTcpForwarding: () => Promise;
getApplicationName: () => Promise;
+ logger: Logger;
};
diff --git a/src/electron/platform/android/setup/live-android-setup-deps.ts b/src/electron/platform/android/setup/live-android-setup-deps.ts
index e53ed55e0ba..2c05039ccc6 100644
--- a/src/electron/platform/android/setup/live-android-setup-deps.ts
+++ b/src/electron/platform/android/setup/live-android-setup-deps.ts
@@ -25,7 +25,7 @@ export class LiveAndroidSetupDeps implements AndroidSetupDeps {
private readonly apkLocator: AndroidServiceApkLocator,
private readonly userConfigMessageCreator: UserConfigMessageCreator,
private readonly fetchDeviceConfig: DeviceConfigFetcher,
- private readonly logger: Logger,
+ public readonly logger: Logger,
) {}
public hasAdbPath = async (): Promise => {
@@ -93,14 +93,8 @@ export class LiveAndroidSetupDeps implements AndroidSetupDeps {
return false;
};
- public setTcpForwarding = async (): Promise => {
- try {
- await this.serviceConfig.setTcpForwarding(this.selectedDeviceId);
- return true;
- } catch (error) {
- this.logger.log(error);
- }
- return false;
+ public setTcpForwarding = async (): Promise => {
+ return await this.serviceConfig.setTcpForwarding(this.selectedDeviceId);
};
public getApplicationName = async (): Promise => {
diff --git a/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts b/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
index ffb05968c4f..904d143d713 100644
--- a/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
+++ b/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
@@ -6,18 +6,19 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const configuringPortForwarding: AndroidSetupStepConfig = deps => ({
actions: {},
onEnter: async () => {
- deps.setApplicationName(); // init
+ try {
+ deps.setScanPort(null);
+ deps.setApplicationName(null);
+ const hostPort = await deps.setTcpForwarding();
+ deps.logger.log(`configured forwarding to tcp:${hostPort}`);
+ const appName = await deps.getApplicationName();
- const configured = await deps.setTcpForwarding();
-
- if (configured === false) {
+ deps.setScanPort(hostPort);
+ deps.setApplicationName(appName);
+ deps.stepTransition('prompt-connected-start-testing');
+ } catch (e) {
+ deps.logger.error(e);
deps.stepTransition('prompt-configuring-port-forwarding-failed');
- return;
}
-
- // device is good to go; so we can get the current app name
- const appName = await deps.getApplicationName();
- deps.setApplicationName(appName);
- deps.stepTransition('prompt-connected-start-testing');
},
});
diff --git a/src/electron/views/automated-checks/automated-checks-view.tsx b/src/electron/views/automated-checks/automated-checks-view.tsx
index a8a759e79b4..387c9332322 100644
--- a/src/electron/views/automated-checks/automated-checks-view.tsx
+++ b/src/electron/views/automated-checks/automated-checks-view.tsx
@@ -30,6 +30,8 @@ import { ScreenshotView } from 'electron/views/screenshot/screenshot-view';
import { ScreenshotViewModelProvider } from 'electron/views/screenshot/screenshot-view-model-provider';
import * as React from 'react';
+import { UnifiedFeatureFlags } from 'electron/common/unified-feature-flags';
+import { AndroidSetupStoreData } from 'electron/flux/types/android-setup-store-data';
import * as styles from './automated-checks-view.scss';
import { CommandBar, CommandBarDeps } from './components/command-bar';
import { HeaderSection } from './components/header-section';
@@ -58,11 +60,12 @@ export type AutomatedChecksViewProps = {
cardSelectionStoreData: CardSelectionStoreData;
detailsViewStoreData: DetailsViewStoreData;
featureFlagStoreData: FeatureFlagStoreData;
+ androidSetupStoreData: AndroidSetupStoreData;
};
export class AutomatedChecksView extends React.Component {
public componentDidMount(): void {
- this.props.deps.scanActionCreator.scan(this.props.deviceStoreData.port);
+ this.props.deps.scanActionCreator.scan(this.getScanPort());
}
public render(): JSX.Element {
@@ -125,7 +128,7 @@ export class AutomatedChecksView extends React.Component
this.props.deps.windowStateActionCreator.setRoute({
routeId: 'deviceConnectView',
})
}
- onRescanDevice={() =>
- this.props.deps.scanActionCreator.scan(this.props.deviceStoreData.port)
- }
+ onRescanDevice={() => this.props.deps.scanActionCreator.scan(this.getScanPort())}
/>
);
}
diff --git a/src/electron/views/automated-checks/components/command-bar.tsx b/src/electron/views/automated-checks/components/command-bar.tsx
index 4a8ca6f566f..3c55d73ceb9 100644
--- a/src/electron/views/automated-checks/components/command-bar.tsx
+++ b/src/electron/views/automated-checks/components/command-bar.tsx
@@ -12,7 +12,6 @@ import {
} from 'DetailsView/components/report-export-component';
import { UnifiedFeatureFlags } from 'electron/common/unified-feature-flags';
import { ScanActionCreator } from 'electron/flux/action-creator/scan-action-creator';
-import { DeviceStoreData } from 'electron/flux/types/device-store-data';
import { ScanStatus } from 'electron/flux/types/scan-status';
import { ScanStoreData } from 'electron/flux/types/scan-store-data';
import * as React from 'react';
@@ -30,7 +29,7 @@ export type CommandBarDeps = {
export interface CommandBarProps {
deps: CommandBarDeps;
- deviceStoreData: DeviceStoreData;
+ scanPort: number;
scanStoreData: ScanStoreData;
featureFlagStoreData: FeatureFlagStoreData;
cardsViewData: CardsViewModel;
@@ -41,7 +40,7 @@ export const commandButtonRefreshId = 'command-button-refresh';
export const commandButtonSettingsId = 'command-button-settings';
export const CommandBar = NamedFC('CommandBar', props => {
- const { deps, deviceStoreData, featureFlagStoreData, cardsViewData, scanMetadata } = props;
+ const { deps, scanPort, featureFlagStoreData, cardsViewData, scanMetadata } = props;
let exportReport = null;
if (scanMetadata != null) {
@@ -73,7 +72,7 @@ export const CommandBar = NamedFC('CommandBar', props => {
data-automation-id={commandButtonRefreshId}
text="Start over"
iconProps={{ iconName: 'Refresh' }}
- onClick={() => deps.scanActionCreator.scan(deviceStoreData.port)}
+ onClick={() => deps.scanActionCreator.scan(scanPort)}
disabled={props.scanStoreData.status === ScanStatus.Scanning}
/>
diff --git a/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts b/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts
index 014619c79ba..ea01507a0e3 100644
--- a/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts
+++ b/src/tests/unit/tests/electron/flux/store/android-setup-store.test.ts
@@ -184,6 +184,36 @@ describe('AndroidSetupStore', () => {
stateMachineFactoryMock.verifyAll();
});
+ it('ensure setScanPort function results in store update', () => {
+ const newScanPort = 63000;
+
+ const initialData: AndroidSetupStoreData = { currentStepId: 'detect-adb' };
+ const expectedData: AndroidSetupStoreData = {
+ currentStepId: 'detect-adb',
+ scanPort: newScanPort,
+ };
+
+ let storeCallbacks: AndroidSetupStoreCallbacks;
+
+ const stateMachineFactoryMock = Mock.ofInstance(mockableStateMachineFactory);
+ stateMachineFactoryMock
+ .setup(m => m(It.isAny()))
+ .callback(sc => (storeCallbacks = sc))
+ .verifiable(Times.once());
+
+ const store = new AndroidSetupStore(
+ new AndroidSetupActions(),
+ stateMachineFactoryMock.object,
+ );
+ store.initialize(initialData);
+
+ storeCallbacks.setScanPort(newScanPort);
+
+ expect(store.getState()).toEqual(expectedData);
+
+ stateMachineFactoryMock.verifyAll();
+ });
+
it('ensure setApplicationName function results in store update', () => {
const appName = 'Star Wars -- Episode Test';
diff --git a/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts b/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts
index 765839b3710..229f8fc6153 100644
--- a/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts
@@ -370,7 +370,8 @@ describe('AppiumServiceConfigurator tests', () => {
.setup(m => m.forwardPort(expectedPortNumber, expectedPortNumber))
.verifiable(Times.once());
- await testSubject.setTcpForwarding(emulatorId);
+ const output = await testSubject.setTcpForwarding(emulatorId);
+ expect(output).toBe(expectedPortNumber);
adbMock.verifyAll();
apkLocatorMock.verifyAll();
diff --git a/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
index e0ae01640c0..ba385ce91c7 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
@@ -409,16 +409,20 @@ describe('LiveAndroidSetupDeps', () => {
verifyAllMocks();
});
- it('setTcpForwarding returns false on error', async () => {
+ it('setTcpForwarding propagates error from serviceConfig.setTcpForwarding', async () => {
+ const deviceId = 'id1';
+ const serviceConfigErrorMessage = 'error from serviceConfig';
serviceConfigMock
- .setup(m => m.setTcpForwarding(undefined))
- .throws(new Error('Threw during setTcpForwarding'))
+ .setup(m => m.setTcpForwarding(deviceId))
+ .returns(() => Promise.reject(new Error(serviceConfigErrorMessage)))
.verifiable(Times.once());
- await initializeServiceConfig();
- const success = await testSubject.setTcpForwarding();
+ await initializeServiceConfig();
- expect(success).toBe(false);
+ testSubject.setSelectedDeviceId(deviceId);
+ await expect(testSubject.setTcpForwarding()).rejects.toThrowError(
+ serviceConfigErrorMessage,
+ );
verifyAllMocks();
});
@@ -442,13 +446,19 @@ describe('LiveAndroidSetupDeps', () => {
verifyAllMocks();
});
- it('setTcpForwarding returns true if no error', async () => {
- serviceConfigMock.setup(m => m.setTcpForwarding(undefined)).verifiable(Times.once());
+ it('setTcpForwarding propagates output from serviceConfig.setTcpForwarding', async () => {
+ const deviceId = 'id1';
+ const serviceConfigOutput = 63000;
+ serviceConfigMock
+ .setup(m => m.setTcpForwarding(deviceId))
+ .returns(() => Promise.resolve(serviceConfigOutput))
+ .verifiable(Times.once());
await initializeServiceConfig();
- const success = await testSubject.setTcpForwarding();
+ testSubject.setSelectedDeviceId(deviceId);
+ const output = await testSubject.setTcpForwarding();
- expect(success).toBe(true);
+ expect(output).toBe(serviceConfigOutput);
verifyAllMocks();
});
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
index 41ffc02ad1c..0569ca3e5af 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
@@ -1,12 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-
import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs';
import { configuringPortForwarding } from 'electron/platform/android/setup/steps/configuring-port-forwarding';
-import { Mock, MockBehavior, Times } from 'typemoq';
+import { IMock, It, Mock, MockBehavior, Times } from 'typemoq';
import { checkExpectedActionsAreDefined } from './actions-tester';
describe('Android setup step: configuringPortForwarding', () => {
+ let mockStoreState: {
+ appName?: string;
+ scanPort?: number;
+ };
+
+ beforeEach(() => {
+ mockStoreState = {
+ appName: null,
+ scanPort: null,
+ };
+ });
+
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = configuringPortForwarding(deps);
@@ -14,44 +25,72 @@ describe('Android setup step: configuringPortForwarding', () => {
expect(step.onEnter).toBeDefined();
});
- it('onEnter transitions to prompt-connected-start-testing on success', async () => {
+ it('onEnter transitions to prompt-connected-start-testing with state set on success', async () => {
+ const scanPort = 63000;
const appName = 'my app name';
- const tcpForwardingPromise = new Promise
(resolve => resolve(true));
- const appNamePromise = new Promise(resolve => resolve(appName));
+ const depsMock = makeMockDepsForMockStore();
- const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock
.setup(m => m.setTcpForwarding())
- .returns(_ => tcpForwardingPromise)
+ .returns(() => Promise.resolve(scanPort))
+ .verifiable(Times.once());
+
+ depsMock
+ .setup(m => m.getApplicationName())
+ .returns(_ => Promise.resolve(appName))
.verifiable(Times.once());
depsMock.setup(m => m.stepTransition('prompt-connected-start-testing'));
+ const step = configuringPortForwarding(depsMock.object);
+ await step.onEnter();
+
+ expect(mockStoreState.appName).toBe(appName);
+ expect(mockStoreState.scanPort).toBe(scanPort);
+ depsMock.verifyAll();
+ });
+
+ it('onEnter transitions to prompt-configuring-port-forwarding-failed with null state on setTcpForwarding failure', async () => {
+ mockStoreState = {
+ appName: 'old name which should get cleared on failure',
+ scanPort: 1,
+ };
+ const depsMock = makeMockDepsForMockStore();
+
depsMock
- .setup(m => m.getApplicationName())
- .returns(_ => appNamePromise)
+ .setup(m => m.setTcpForwarding())
+ .returns(() => Promise.reject(new Error('test error')))
.verifiable(Times.once());
- depsMock.setup(m => m.setApplicationName(undefined)).verifiable(Times.once());
- depsMock.setup(m => m.setApplicationName(appName)).verifiable(Times.once());
+ depsMock
+ .setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
+ .verifiable(Times.once());
const step = configuringPortForwarding(depsMock.object);
await step.onEnter();
+ expect(mockStoreState.appName).toBeNull();
+ expect(mockStoreState.scanPort).toBeNull();
depsMock.verifyAll();
});
- it('onEnter transitions to prompt-configuring-port-forwarding-failed on failure', async () => {
- const p = new Promise(resolve => resolve(false));
+ it('onEnter transitions to prompt-configuring-port-forwarding-failed with null state on getApplicationName failure', async () => {
+ mockStoreState = {
+ appName: 'old name which should get cleared on failure',
+ scanPort: 1,
+ };
+ const depsMock = makeMockDepsForMockStore();
- const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock
.setup(m => m.setTcpForwarding())
- .returns(_ => p)
+ .returns(() => Promise.resolve(2))
.verifiable(Times.once());
- depsMock.setup(m => m.setApplicationName(undefined)).verifiable(Times.once());
+ depsMock
+ .setup(m => m.getApplicationName())
+ .returns(() => Promise.reject(new Error('error from getApplicationName')))
+ .verifiable(Times.once());
depsMock
.setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
@@ -60,6 +99,40 @@ describe('Android setup step: configuringPortForwarding', () => {
const step = configuringPortForwarding(depsMock.object);
await step.onEnter();
+ expect(mockStoreState.appName).toBeNull(); // not 2
+ expect(mockStoreState.scanPort).toBeNull();
depsMock.verifyAll();
});
+
+ function makeMockDepsForMockStore(): IMock {
+ const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
+
+ depsMock
+ .setup(m => m.logger)
+ .returns(() => ({
+ log: () => {},
+ error: () => {},
+ }))
+ // We don't care how many times this is invoked
+ .verifiable(Times.atLeast(0));
+
+ depsMock
+ .setup(m => m.setScanPort(It.isAny()))
+ .callback(newPort => {
+ mockStoreState.scanPort = newPort;
+ })
+ // We don't care how many times this is invoked, we only care about the final mockStoreState
+ .verifiable(Times.atLeastOnce());
+
+ depsMock
+ .setup(m => m.setApplicationName(It.isAny()))
+ .callback(newName => {
+ mockStoreState.appName = newName;
+ })
+ // We don't care how many times this is invoked, we only care about the final mockStoreState
+
+ .verifiable(Times.atLeastOnce());
+
+ return depsMock;
+ }
});
diff --git a/src/tests/unit/tests/electron/views/automated-checks/__snapshots__/automated-checks-view.test.tsx.snap b/src/tests/unit/tests/electron/views/automated-checks/__snapshots__/automated-checks-view.test.tsx.snap
index 6c91e5c405c..c7fe5076381 100644
--- a/src/tests/unit/tests/electron/views/automated-checks/__snapshots__/automated-checks-view.test.tsx.snap
+++ b/src/tests/unit/tests/electron/views/automated-checks/__snapshots__/automated-checks-view.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`AutomatedChecksView renders when status scan 1`] = `
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=false when status scan 1`] = `
1`] = `
},
}
}
- deviceStoreData={Object {}}
+ featureFlagStoreData={
+ Object {
+ "adbSetupView": false,
+ }
+ }
+ scanMetadata={
+ Object {
+ "deviceName": "TEST DEVICE",
+ "targetAppInfo": Object {
+ "name": "test-target-app-name",
+ },
+ "timestamp": "test timestamp",
+ "toolData": Object {
+ "applicationProperties": Object {
+ "name": "some app",
+ },
+ },
+ }
+ }
+ scanStoreData={
+ Object {
+ "status": 2,
+ }
+ }
+ />
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=false when status scan
1`] = `
+
+`;
+
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=false when status scan 1`] = `
+
+`;
+
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=false when status scan 1`] = `
+
+`;
+
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=true when status scan 1`] = `
+
+
+
+
+ 1`] = `
`;
-exports[`AutomatedChecksView renders when status scan
1`] = `
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=true when status scan 1`] = `
1`] = `
},
}
}
- deviceStoreData={
+ featureFlagStoreData={
Object {
- "connectedDevice": "TEST DEVICE",
+ "adbSetupView": true,
}
}
scanMetadata={null}
+ scanPort={63000}
scanStoreData={
Object {
"status": 3,
@@ -239,7 +704,7 @@ exports[`AutomatedChecksView renders when status scan 1`] = `
@@ -269,7 +734,7 @@ exports[`AutomatedChecksView renders when status scan 1`] = `
`;
-exports[`AutomatedChecksView renders when status scan 1`] = `
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=true when status scan 1`] = `
1`] = `
},
}
}
- deviceStoreData={
+ featureFlagStoreData={
Object {
- "connectedDevice": "TEST DEVICE",
+ "adbSetupView": true,
}
}
scanMetadata={null}
+ scanPort={63000}
scanStoreData={
Object {
"status": 1,
@@ -361,7 +827,7 @@ exports[`AutomatedChecksView renders when status scan 1`] = `
`;
-exports[`AutomatedChecksView renders when status scan 1`] = `
+exports[`AutomatedChecksView renders with adbSetupViewFeatureFlag=true when status scan 1`] = `
1`] = `
},
}
}
- deviceStoreData={
+ featureFlagStoreData={
Object {
- "connectedDevice": "TEST DEVICE",
+ "adbSetupView": true,
}
}
scanMetadata={null}
+ scanPort={63000}
scanStoreData={
Object {
"status": undefined,
diff --git a/src/tests/unit/tests/electron/views/automated-checks/automated-checks-view.test.tsx b/src/tests/unit/tests/electron/views/automated-checks/automated-checks-view.test.tsx
index 168f9232f1a..d93772d9e81 100644
--- a/src/tests/unit/tests/electron/views/automated-checks/automated-checks-view.test.tsx
+++ b/src/tests/unit/tests/electron/views/automated-checks/automated-checks-view.test.tsx
@@ -13,6 +13,7 @@ import {
CardRuleResultsByStatus,
CardsViewModel,
} from 'common/types/store-data/card-view-model';
+import { FeatureFlagStoreData } from 'common/types/store-data/feature-flag-store-data';
import {
PlatformData,
ToolData,
@@ -20,6 +21,7 @@ import {
UnifiedRule,
UnifiedScanResultStoreData,
} from 'common/types/store-data/unified-data-interface';
+import { UnifiedFeatureFlags } from 'electron/common/unified-feature-flags';
import { ScanActionCreator } from 'electron/flux/action-creator/scan-action-creator';
import { WindowStateActionCreator } from 'electron/flux/action-creator/window-state-action-creator';
import { ScanStatus } from 'electron/flux/types/scan-status';
@@ -35,160 +37,212 @@ import * as React from 'react';
import { It, Mock, Times } from 'typemoq';
describe('AutomatedChecksView', () => {
- describe('renders', () => {
- let bareMinimumProps: AutomatedChecksViewProps;
- let isResultHighlightUnavailableStub: IsResultHighlightUnavailable;
-
- beforeEach(() => {
- isResultHighlightUnavailableStub = () => null;
- bareMinimumProps = {
- deps: {
- windowStateActionCreator: Mock.ofType(WindowStateActionCreator).object,
- scanActionCreator: Mock.ofType(ScanActionCreator).object,
- isResultHighlightUnavailable: isResultHighlightUnavailableStub,
- },
- scanStoreData: {},
- deviceStoreData: {
- connectedDevice: 'TEST DEVICE',
- },
- detailsViewStoreData: {
- currentPanel: { isSettingsOpen: false },
- },
- windowStateStoreData: 'window state store data' as any,
- } as AutomatedChecksViewProps;
- });
-
- const scanStatuses = [
- undefined,
- ScanStatus[ScanStatus.Scanning],
- ScanStatus[ScanStatus.Failed],
- ];
-
- it.each(scanStatuses)('when status scan <%s>', scanStatusName => {
- bareMinimumProps.scanStoreData.status = ScanStatus[scanStatusName];
-
- const wrapped = shallow(
);
- expect(wrapped.getElement()).toMatchSnapshot();
- });
-
- it('when status scan
', () => {
- const cardSelectionStoreData = {} as CardSelectionStoreData;
- const resultsHighlightStatus = {
- 'highlighted-uid-1': 'visible',
- 'not-highlighted-uid-1': 'hidden',
- } as ResultsHighlightStatus;
- const timeStampStub = 'test timestamp';
- const toolDataStub: ToolData = {
- applicationProperties: { name: 'some app' },
- } as ToolData;
-
- const cardSelectionViewDataStub = {
- resultsHighlightStatus: resultsHighlightStatus,
- } as CardSelectionViewData;
- const rulesStub = [{ description: 'test-rule-description' } as UnifiedRule];
- const resultsStub = [
- { uid: 'highlighted-uid-1' },
- { uid: 'not-highlighted-uid-1' },
- ] as UnifiedResult[];
- const unifiedScanResultStoreData: UnifiedScanResultStoreData = {
- targetAppInfo: {
- name: 'test-target-app-name',
- },
- rules: rulesStub,
- results: resultsStub,
- toolInfo: toolDataStub,
- timestamp: timeStampStub,
- platformInfo: {
- deviceName: 'TEST DEVICE',
- } as PlatformData,
- };
-
- const ruleResultsByStatusStub = {
- fail: [{ id: 'test-fail-id' } as CardRuleResult],
- } as CardRuleResultsByStatus;
- const cardsViewData = {
- cards: ruleResultsByStatusStub,
- } as CardsViewModel;
- const screenshotViewModelStub = {
- screenshotData: {
- base64PngData: 'this should appear in snapshotted ScreenshotView props',
- },
- } as ScreenshotViewModel;
- const screenshotViewModelProviderMock = Mock.ofInstance(screenshotViewModelProvider);
- const getCardSelectionViewDataMock = Mock.ofInstance(getCardSelectionViewData);
- const getUnifiedRuleResultsMock = Mock.ofInstance(getCardViewData);
-
- const props: AutomatedChecksViewProps = {
- deps: {
- scanActionCreator: Mock.ofType(ScanActionCreator).object,
- getCardsViewData: getUnifiedRuleResultsMock.object,
- getCardSelectionViewData: getCardSelectionViewDataMock.object,
- screenshotViewModelProvider: screenshotViewModelProviderMock.object,
- isResultHighlightUnavailable: isResultHighlightUnavailableStub,
- },
- cardSelectionStoreData,
- deviceStoreData: {},
- scanStoreData: {
- status: ScanStatus.Completed,
- },
- userConfigurationStoreData: {
- isFirstTime: false,
- },
- detailsViewStoreData: {
- currentPanel: {},
- },
- unifiedScanResultStoreData,
- } as AutomatedChecksViewProps;
+ describe.each`
+ adbSetupViewFeatureFlag
+ ${true}
+ ${false}
+ `(
+ 'renders with adbSetupViewFeatureFlag=$adbSetupViewFeatureFlag',
+ ({ adbSetupViewFeatureFlag }) => {
+ let bareMinimumProps: AutomatedChecksViewProps;
+ let isResultHighlightUnavailableStub: IsResultHighlightUnavailable;
+
+ beforeEach(() => {
+ isResultHighlightUnavailableStub = () => null;
+ bareMinimumProps = {
+ deps: {
+ windowStateActionCreator: Mock.ofType(WindowStateActionCreator).object,
+ scanActionCreator: Mock.ofType(ScanActionCreator).object,
+ isResultHighlightUnavailable: isResultHighlightUnavailableStub,
+ },
+ scanStoreData: {},
+ deviceStoreData: {
+ port: 62442,
+ connectedDevice: 'Device name from deviceStoreData',
+ },
+ androidSetupStoreData: {
+ scanPort: 63000,
+ selectedDevice: {
+ friendlyName: 'Device name from androidSetupStoreData',
+ },
+ },
+ detailsViewStoreData: {
+ currentPanel: { isSettingsOpen: false },
+ },
+ windowStateStoreData: 'window state store data' as any,
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: adbSetupViewFeatureFlag,
+ } as FeatureFlagStoreData,
+ } as AutomatedChecksViewProps;
+ });
+
+ const scanStatuses = [
+ undefined,
+ ScanStatus[ScanStatus.Scanning],
+ ScanStatus[ScanStatus.Failed],
+ ];
+
+ it.each(scanStatuses)('when status scan <%s>', scanStatusName => {
+ bareMinimumProps.scanStoreData.status = ScanStatus[scanStatusName];
+
+ const wrapped = shallow();
+ expect(wrapped.getElement()).toMatchSnapshot();
+ });
+
+ it('when status scan ', () => {
+ const cardSelectionStoreData = {} as CardSelectionStoreData;
+ const resultsHighlightStatus = {
+ 'highlighted-uid-1': 'visible',
+ 'not-highlighted-uid-1': 'hidden',
+ } as ResultsHighlightStatus;
+ const timeStampStub = 'test timestamp';
+ const toolDataStub: ToolData = {
+ applicationProperties: { name: 'some app' },
+ } as ToolData;
+
+ const cardSelectionViewDataStub = {
+ resultsHighlightStatus: resultsHighlightStatus,
+ } as CardSelectionViewData;
+ const rulesStub = [{ description: 'test-rule-description' } as UnifiedRule];
+ const resultsStub = [
+ { uid: 'highlighted-uid-1' },
+ { uid: 'not-highlighted-uid-1' },
+ ] as UnifiedResult[];
+ const unifiedScanResultStoreData: UnifiedScanResultStoreData = {
+ targetAppInfo: {
+ name: 'test-target-app-name',
+ },
+ rules: rulesStub,
+ results: resultsStub,
+ toolInfo: toolDataStub,
+ timestamp: timeStampStub,
+ platformInfo: {
+ deviceName: 'TEST DEVICE',
+ } as PlatformData,
+ };
+
+ const ruleResultsByStatusStub = {
+ fail: [{ id: 'test-fail-id' } as CardRuleResult],
+ } as CardRuleResultsByStatus;
+ const cardsViewData = {
+ cards: ruleResultsByStatusStub,
+ } as CardsViewModel;
+ const screenshotViewModelStub = {
+ screenshotData: {
+ base64PngData: 'this should appear in snapshotted ScreenshotView props',
+ },
+ } as ScreenshotViewModel;
+ const screenshotViewModelProviderMock = Mock.ofInstance(
+ screenshotViewModelProvider,
+ );
+ const getCardSelectionViewDataMock = Mock.ofInstance(getCardSelectionViewData);
+ const getUnifiedRuleResultsMock = Mock.ofInstance(getCardViewData);
+
+ const props: AutomatedChecksViewProps = {
+ deps: {
+ scanActionCreator: Mock.ofType(ScanActionCreator).object,
+ getCardsViewData: getUnifiedRuleResultsMock.object,
+ getCardSelectionViewData: getCardSelectionViewDataMock.object,
+ screenshotViewModelProvider: screenshotViewModelProviderMock.object,
+ isResultHighlightUnavailable: isResultHighlightUnavailableStub,
+ },
+ cardSelectionStoreData,
+ deviceStoreData: {},
+ androidSetupStoreData: {},
+ scanStoreData: {
+ status: ScanStatus.Completed,
+ },
+ userConfigurationStoreData: {
+ isFirstTime: false,
+ },
+ detailsViewStoreData: {
+ currentPanel: {},
+ },
+ unifiedScanResultStoreData,
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: adbSetupViewFeatureFlag,
+ } as FeatureFlagStoreData,
+ } as AutomatedChecksViewProps;
+
+ getCardSelectionViewDataMock
+ .setup(getData =>
+ getData(
+ cardSelectionStoreData,
+ unifiedScanResultStoreData,
+ isResultHighlightUnavailableStub,
+ ),
+ )
+ .returns(() => cardSelectionViewDataStub)
+ .verifiable(Times.once());
+
+ getUnifiedRuleResultsMock
+ .setup(getter => getter(rulesStub, resultsStub, cardSelectionViewDataStub))
+ .returns(() => cardsViewData)
+ .verifiable(Times.once());
+
+ screenshotViewModelProviderMock
+ .setup(provider => provider(unifiedScanResultStoreData, ['highlighted-uid-1']))
+ .returns(() => screenshotViewModelStub)
+ .verifiable(Times.once());
+
+ const wrapped = shallow();
+
+ expect(wrapped.getElement()).toMatchSnapshot();
+
+ getCardSelectionViewDataMock.verifyAll();
+ getUnifiedRuleResultsMock.verifyAll();
+ screenshotViewModelProviderMock.verifyAll();
+ });
+ },
+ );
+
+ it('triggers scan when first mounted (non-adbSetupView)', () => {
+ const port = 11111;
- getCardSelectionViewDataMock
- .setup(getData =>
- getData(
- cardSelectionStoreData,
- unifiedScanResultStoreData,
- isResultHighlightUnavailableStub,
- ),
- )
- .returns(() => cardSelectionViewDataStub)
- .verifiable(Times.once());
-
- getUnifiedRuleResultsMock
- .setup(getter => getter(rulesStub, resultsStub, cardSelectionViewDataStub))
- .returns(() => cardsViewData)
- .verifiable(Times.once());
-
- screenshotViewModelProviderMock
- .setup(provider => provider(unifiedScanResultStoreData, ['highlighted-uid-1']))
- .returns(() => screenshotViewModelStub)
- .verifiable(Times.once());
+ const scanActionCreatorMock = Mock.ofType(ScanActionCreator);
+ scanActionCreatorMock.setup(creator => creator.scan(port)).verifiable(Times.once());
- const wrapped = shallow();
+ const props: AutomatedChecksViewProps = {
+ deps: {
+ scanActionCreator: scanActionCreatorMock.object,
+ },
+ scanStoreData: {},
+ deviceStoreData: {
+ port,
+ },
+ detailsViewStoreData: {
+ currentPanel: {},
+ },
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: false,
+ } as FeatureFlagStoreData,
+ } as AutomatedChecksViewProps;
- expect(wrapped.getElement()).toMatchSnapshot();
+ shallow();
- getCardSelectionViewDataMock.verifyAll();
- getUnifiedRuleResultsMock.verifyAll();
- screenshotViewModelProviderMock.verifyAll();
- });
+ scanActionCreatorMock.verifyAll();
});
- it('triggers scan when first mounted', () => {
- const port = 11111;
+ it('triggers scan when first mounted (adbSetupView)', () => {
+ const scanPort = 11111;
const scanActionCreatorMock = Mock.ofType(ScanActionCreator);
- scanActionCreatorMock.setup(creator => creator.scan(port)).verifiable(Times.once());
+ scanActionCreatorMock.setup(creator => creator.scan(scanPort)).verifiable(Times.once());
const props: AutomatedChecksViewProps = {
deps: {
scanActionCreator: scanActionCreatorMock.object,
},
scanStoreData: {},
- deviceStoreData: {
- port,
+ androidSetupStoreData: {
+ scanPort,
},
-
detailsViewStoreData: {
currentPanel: {},
},
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: true,
+ } as FeatureFlagStoreData,
} as AutomatedChecksViewProps;
shallow();
@@ -197,7 +251,7 @@ describe('AutomatedChecksView', () => {
});
describe('DeviceDisconnectedPopup event handlers', () => {
- it('onRescanDevice', () => {
+ it('onRescanDevice (non-adbSetupView)', () => {
const port = 11111;
const scanActionCreatorMock = Mock.ofType(ScanActionCreator);
@@ -215,6 +269,9 @@ describe('AutomatedChecksView', () => {
detailsViewStoreData: {
currentPanel: {},
},
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: false,
+ } as FeatureFlagStoreData,
} as AutomatedChecksViewProps;
const wrapped = shallow();
@@ -226,6 +283,38 @@ describe('AutomatedChecksView', () => {
scanActionCreatorMock.verify(creator => creator.scan(port), Times.once());
});
+ it('onRescanDevice (adbSetupView)', () => {
+ const scanPort = 11111;
+
+ const scanActionCreatorMock = Mock.ofType(ScanActionCreator);
+
+ const props: AutomatedChecksViewProps = {
+ deps: {
+ scanActionCreator: scanActionCreatorMock.object,
+ },
+ scanStoreData: {
+ status: ScanStatus.Failed,
+ },
+ androidSetupStoreData: {
+ scanPort,
+ },
+ detailsViewStoreData: {
+ currentPanel: {},
+ },
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: true,
+ } as FeatureFlagStoreData,
+ } as AutomatedChecksViewProps;
+
+ const wrapped = shallow();
+
+ scanActionCreatorMock.reset(); // this mock is used on componentDidMount, which is not in the scope of this unit test
+
+ wrapped.find(DeviceDisconnectedPopup).prop('onRescanDevice')();
+
+ scanActionCreatorMock.verify(creator => creator.scan(scanPort), Times.once());
+ });
+
it('onConnectNewDevice', () => {
const scanActionCreatorMock = Mock.ofType(ScanActionCreator);
const windowStateActionCreatorMock = Mock.ofType(WindowStateActionCreator);
@@ -242,6 +331,9 @@ describe('AutomatedChecksView', () => {
detailsViewStoreData: {
currentPanel: {},
},
+ featureFlagStoreData: {
+ [UnifiedFeatureFlags.adbSetupView]: false,
+ } as FeatureFlagStoreData,
} as AutomatedChecksViewProps;
const wrapped = shallow();
diff --git a/src/tests/unit/tests/electron/views/automated-checks/components/command-bar.test.tsx b/src/tests/unit/tests/electron/views/automated-checks/components/command-bar.test.tsx
index 56c75099c25..11ae196157e 100644
--- a/src/tests/unit/tests/electron/views/automated-checks/components/command-bar.test.tsx
+++ b/src/tests/unit/tests/electron/views/automated-checks/components/command-bar.test.tsx
@@ -132,9 +132,7 @@ describe('CommandBar', () => {
getDateFromTimestamp: getDateFromTimestampMock.object,
reportGenerator: reportGeneratorMock.object,
},
- deviceStoreData: {
- port,
- },
+ scanPort: port,
scanStoreData: {
status: ScanStatus.Default,
},
From 42d196c322659c6065aadeaed749fe93d0c40298 Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Mon, 22 Jun 2020 15:10:51 -0700
Subject: [PATCH 64/71] fix(android-setup): Connect cancel button in "start
testing" dialog (#2935)
---
.../setup/steps/prompt-connected-start-testing.ts | 3 +++
.../steps/prompt-connected-start-testing.test.ts | 12 +++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts b/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts
index 679b925cf48..a54b8328a7c 100644
--- a/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts
+++ b/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts
@@ -5,6 +5,9 @@ import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-
export const promptConnectedStartTesting: AndroidSetupStepConfig = deps => ({
actions: {
+ cancel: () => {
+ deps.stepTransition('prompt-choose-device');
+ },
rescan: () => {
deps.stepTransition('detect-adb');
},
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts
index ddd9f9b0398..e47446e2259 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts
@@ -10,10 +10,20 @@ describe('Android setup step: promptConnectedStartTesting', () => {
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = promptConnectedStartTesting(deps);
- checkExpectedActionsAreDefined(step, ['rescan']);
+ checkExpectedActionsAreDefined(step, ['cancel', 'rescan']);
expect(step.onEnter).not.toBeDefined();
});
+ it('cancel transitions to prompt-choose-device', async () => {
+ const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
+ depsMock.setup(m => m.stepTransition('prompt-choose-device')).verifiable(Times.once());
+
+ const step = promptConnectedStartTesting(depsMock.object);
+ step.actions.cancel();
+
+ depsMock.verifyAll();
+ });
+
it('rescan transitions to detect-adb as expected', () => {
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
depsMock.setup(m => m.stepTransition('detect-adb')).verifiable(Times.once());
From bbcfdc0d313ace87272fc9578f35799333c0c1ce Mon Sep 17 00:00:00 2001
From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com>
Date: Tue, 23 Jun 2020 09:19:59 -0700
Subject: [PATCH 65/71] fix(android-setup): Enable selection from multiple
devices (#2937)
---
.../android/setup/android-setup-steps-configs.ts | 3 ++-
.../android-setup/prompt-choose-device-step.tsx | 5 ++++-
.../android-setup/prompt-choose-device-step.test.tsx | 9 ++++++---
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/electron/platform/android/setup/android-setup-steps-configs.ts b/src/electron/platform/android/setup/android-setup-steps-configs.ts
index 06965263f49..372ce5d87a1 100644
--- a/src/electron/platform/android/setup/android-setup-steps-configs.ts
+++ b/src/electron/platform/android/setup/android-setup-steps-configs.ts
@@ -10,6 +10,7 @@ import { detectDevices } from 'electron/platform/android/setup/steps/detect-devi
import { detectPermissions } from 'electron/platform/android/setup/steps/detect-permissions';
import { detectService } from 'electron/platform/android/setup/steps/detect-service';
import { installingService } from 'electron/platform/android/setup/steps/installing-service';
+import { promptChooseDevice } from 'electron/platform/android/setup/steps/prompt-choose-device';
import { promptConfiguringPortForwardingFailed } from 'electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed';
import { promptConnectToDevice } from 'electron/platform/android/setup/steps/prompt-connect-to-device';
import { promptConnectedStartTesting } from 'electron/platform/android/setup/steps/prompt-connected-start-testing';
@@ -40,7 +41,7 @@ export const allAndroidSetupStepConfigs: AndroidSetupStepConfigs = {
'prompt-locate-adb': promptLocateAdb,
'prompt-connect-to-device': promptConnectToDevice,
'detect-devices': detectDevices,
- 'prompt-choose-device': promptConnectToDevice,
+ 'prompt-choose-device': promptChooseDevice,
'detect-service': detectService,
'prompt-install-service': promptInstallService,
'installing-service': installingService,
diff --git a/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx b/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx
index e6c75f7c7eb..c2e4fcc59aa 100644
--- a/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx
+++ b/src/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.tsx
@@ -90,7 +90,10 @@ export class PromptChooseDeviceStep extends React.Component<
rightFooterButtonProps: {
text: 'Next',
disabled: this.state.selectedDevice === null,
- onClick: _ => this.props.deps.androidSetupActionCreator.next(),
+ onClick: _ => {
+ const selectedDevice: DeviceInfo = this.state.selectedDevice['metadata'];
+ this.props.deps.androidSetupActionCreator.setSelectedDevice(selectedDevice);
+ },
},
};
diff --git a/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx b/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx
index 4f656b6010d..4eb95363bed 100644
--- a/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx
+++ b/src/tests/unit/tests/electron/views/device-connect-view/components/android-setup/prompt-choose-device-step.test.tsx
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
import { AndroidSetupActionCreator } from 'electron/flux/action-creator/android-setup-action-creator';
import { AndroidSetupStoreData } from 'electron/flux/types/android-setup-store-data';
+import { DeviceInfo } from 'electron/platform/android/android-service-configurator';
import { AndroidSetupStepLayout } from 'electron/views/device-connect-view/components/android-setup/android-setup-step-layout';
import { CommonAndroidSetupStepProps } from 'electron/views/device-connect-view/components/android-setup/android-setup-types';
import { PromptChooseDeviceStep } from 'electron/views/device-connect-view/components/android-setup/prompt-choose-device-step';
@@ -63,11 +64,13 @@ describe('PromptChooseDeviceStep', () => {
actionMessageCreatorMock.verify(m => m.rescan(), Times.once());
});
- it('passes next dep through', () => {
+ it('passes setSelectedDevice dep through', () => {
+ const expectedDevice: DeviceInfo = props.androidSetupStoreData.availableDevices[0];
const stubEvent = {} as React.MouseEvent;
- const rendered = shallow();
+ const rendered = mount();
+ rendered.find('DeviceDescription').at(0).simulate('click');
rendered.find(AndroidSetupStepLayout).prop('rightFooterButtonProps').onClick(stubEvent);
- actionMessageCreatorMock.verify(m => m.next(), Times.once());
+ actionMessageCreatorMock.verify(m => m.setSelectedDevice(expectedDevice), Times.once());
});
it('next button becomes enabled after device is selected', () => {
From adab23d9dc08550dda571e5480cbbd3039fd326f Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Tue, 23 Jun 2020 18:10:41 +0000
Subject: [PATCH 66/71] chore(deps-dev): bump ts-jest from 26.1.0 to 26.1.1
(#2938)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index edbb1c65ea1..5c09e04a14b 100644
--- a/package.json
+++ b/package.json
@@ -125,7 +125,7 @@
"source-map-loader": "^1.0.0",
"spectron": "^10.0.1",
"terser-webpack-plugin": "^3.0.6",
- "ts-jest": "^26.1.0",
+ "ts-jest": "^26.1.1",
"ts-loader": "^7.0.5",
"tslint": "^5.20.1",
"tslint-microsoft-contrib": "6.2.0",
diff --git a/yarn.lock b/yarn.lock
index bbef68c981d..25022278612 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10780,10 +10780,10 @@ truncate-utf8-bytes@^1.0.0:
dependencies:
utf8-byte-length "^1.0.1"
-ts-jest@^26.1.0:
- version "26.1.0"
- resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.1.0.tgz#e9070fc97b3ea5557a48b67c631c74eb35e15417"
- integrity sha512-JbhQdyDMYN5nfKXaAwCIyaWLGwevcT2/dbqRPsQeh6NZPUuXjZQZEfeLb75tz0ubCIgEELNm6xAzTe5NXs5Y4Q==
+ts-jest@^26.1.1:
+ version "26.1.1"
+ resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.1.1.tgz#b98569b8a4d4025d966b3d40c81986dd1c510f8d"
+ integrity sha512-Lk/357quLg5jJFyBQLnSbhycnB3FPe+e9i7ahxokyXxAYoB0q1pPmqxxRPYr4smJic1Rjcf7MXDBhZWgxlli0A==
dependencies:
bs-logger "0.x"
buffer-from "1.x"
From d9d6176a75d86399b8b2111eb55d981069a6657c Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Tue, 23 Jun 2020 18:10:53 +0000
Subject: [PATCH 67/71] chore(deps-dev): bump jest-junit from 10.0.0 to 11.0.1
(#2939)
---
package.json | 2 +-
yarn.lock | 60 +++++++---------------------------------------------
2 files changed, 9 insertions(+), 53 deletions(-)
diff --git a/package.json b/package.json
index 5c09e04a14b..e5e310dc225 100644
--- a/package.json
+++ b/package.json
@@ -106,7 +106,7 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^26.0.1",
"jest-circus": "^26.0.1",
- "jest-junit": "^10.0.0",
+ "jest-junit": "^11.0.1",
"js-yaml": "^3.14.0",
"license-check-and-add": "^3.0.4",
"make-dir": "^3.1.0",
diff --git a/yarn.lock b/yarn.lock
index 25022278612..3c8c62ce7a5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -520,15 +520,6 @@
source-map "^0.6.1"
write-file-atomic "^3.0.0"
-"@jest/types@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
- integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^1.1.1"
- "@types/yargs" "^13.0.0"
-
"@jest/types@^25.5.0":
version "25.5.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d"
@@ -1299,13 +1290,6 @@
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228"
integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==
-"@types/yargs@^13.0.0":
- version "13.0.3"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380"
- integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==
- dependencies:
- "@types/yargs-parser" "*"
-
"@types/yargs@^15.0.0", "@types/yargs@^15.0.5":
version "15.0.5"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.5.tgz#947e9a6561483bdee9adffc983e91a6902af8b79"
@@ -1697,7 +1681,7 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
-ansi-regex@^4.0.0, ansi-regex@^4.1.0:
+ansi-regex@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
@@ -1712,7 +1696,7 @@ ansi-styles@^2.2.1:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-ansi-styles@^3.2.0, ansi-styles@^3.2.1:
+ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
@@ -6304,11 +6288,6 @@ jest-environment-node@^26.0.1:
jest-mock "^26.0.1"
jest-util "^26.0.1"
-jest-get-type@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e"
- integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==
-
jest-get-type@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
@@ -6362,13 +6341,12 @@ jest-jasmine2@^26.0.1:
pretty-format "^26.0.1"
throat "^5.0.0"
-jest-junit@^10.0.0:
- version "10.0.0"
- resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-10.0.0.tgz#c94b91c24920a327c9d2a075e897b2dba4af494b"
- integrity sha512-dbOVRyxHprdSpwSAR9/YshLwmnwf+RSl5hf0kCGlhAcEeZY9aRqo4oNmaT0tLC16Zy9D0zekDjWkjHGjXlglaQ==
+jest-junit@^11.0.1:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-11.0.1.tgz#944b997b7318efd1f021b4f0fce4937f8d66f392"
+ integrity sha512-stgc0mBoiSg/F9qWd4KkmR3K7Nk2u+M/dc1oup7gxz9mrzGcEaU2YL9/0QscVqqg3IOaA1P5ZXtozG/XR6j6nw==
dependencies:
- jest-validate "^24.9.0"
- mkdirp "^0.5.1"
+ mkdirp "^1.0.4"
strip-ansi "^5.2.0"
uuid "^3.3.3"
xml "^1.0.1"
@@ -6541,18 +6519,6 @@ jest-util@^26.0.1:
is-ci "^2.0.0"
make-dir "^3.0.0"
-jest-validate@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab"
- integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==
- dependencies:
- "@jest/types" "^24.9.0"
- camelcase "^5.3.1"
- chalk "^2.0.1"
- jest-get-type "^24.9.0"
- leven "^3.1.0"
- pretty-format "^24.9.0"
-
jest-validate@^26.0.1:
version "26.0.1"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.0.1.tgz#a62987e1da5b7f724130f904725e22f4e5b2e23c"
@@ -8589,16 +8555,6 @@ pretty-bytes@^1.0.2:
get-stdin "^4.0.1"
meow "^3.1.0"
-pretty-format@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9"
- integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==
- dependencies:
- "@jest/types" "^24.9.0"
- ansi-regex "^4.0.0"
- ansi-styles "^3.2.0"
- react-is "^16.8.4"
-
pretty-format@^25.2.1, pretty-format@^25.2.6:
version "25.5.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a"
@@ -8956,7 +8912,7 @@ react-helmet@^6.1.0:
react-fast-compare "^3.1.1"
react-side-effect "^2.1.0"
-react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
+react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
From bf0aadfdbc48727284898eb3004a24805eee95b9 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Tue, 23 Jun 2020 18:11:03 +0000
Subject: [PATCH 68/71] chore(deps): bump appium-adb from 8.6.1 to 8.6.2
(#2940)
---
package.json | 2 +-
yarn.lock | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/package.json b/package.json
index e5e310dc225..e59d8a5cb04 100644
--- a/package.json
+++ b/package.json
@@ -139,7 +139,7 @@
},
"dependencies": {
"accessibility-insights-for-android-service-bin": "^1.2.0",
- "appium-adb": "^8.6.1",
+ "appium-adb": "^8.6.2",
"applicationinsights-js": "^1.0.21",
"axe-core": "3.5.1",
"axios": "^0.19.2",
diff --git a/yarn.lock b/yarn.lock
index 3c8c62ce7a5..ed35ec18f1b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1765,16 +1765,16 @@ app-builder-lib@22.7.0, app-builder-lib@^22.6.1:
semver "^7.3.2"
temp-file "^3.3.7"
-appium-adb@^8.6.1:
- version "8.6.1"
- resolved "https://registry.yarnpkg.com/appium-adb/-/appium-adb-8.6.1.tgz#1cb41c2f98ce40fccdf84c23dc65cc34f18dc2b2"
- integrity sha512-Klz6M05dA1xKfoUVURTCx6tfaIUl/IoLDekI/g06PBhUB5AcaxfmZirY+ZMcTcc8uGr0CN9pqIqI7GvhSMjxhg==
+appium-adb@^8.6.2:
+ version "8.6.2"
+ resolved "https://registry.yarnpkg.com/appium-adb/-/appium-adb-8.6.2.tgz#be0294f85cab517acf57465a794ff6010dfbef78"
+ integrity sha512-jAvyjAGtAb/XzUOZ/vQzKQhn17z2ooqHKfi8armU260jHSj4q/fuILkNoVC9r6sCwn8pzaX4FmikEMxqYOJiMg==
dependencies:
"@babel/runtime" "^7.0.0"
adbkit-apkreader "^3.1.2"
appium-support "^2.42.0"
async-lock "^1.0.0"
- asyncbox "^2.3.1"
+ asyncbox "^2.6.0"
bluebird "^3.4.7"
lodash "^4.0.0"
lru-cache "^5.0.0"
@@ -2054,7 +2054,7 @@ async@~1.5.2:
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-asyncbox@^2.3.1:
+asyncbox@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/asyncbox/-/asyncbox-2.6.0.tgz#ded2db43b14c4d14340d18d4898e5d63de2ffb42"
integrity sha512-x9RDH0Dk4qZIGHQc9KbnDrUnaEbtWJW2DbuSElOFOQ2ppGsT1eFEDsiconZPpRGMW6+Uv724FYaBc8SUvyWVzA==
From fb8ae8326ef25500851d6c6dbec64ceb350b962b Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Tue, 23 Jun 2020 18:11:20 +0000
Subject: [PATCH 69/71] chore(deps-dev): bump simple-git from 2.8.0 to 2.9.0
(#2941)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index e59d8a5cb04..21db5e23e1b 100644
--- a/package.json
+++ b/package.json
@@ -121,7 +121,7 @@
"sass-loader": "^8.0.2",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
- "simple-git": "^2.8.0",
+ "simple-git": "^2.9.0",
"source-map-loader": "^1.0.0",
"spectron": "^10.0.1",
"terser-webpack-plugin": "^3.0.6",
diff --git a/yarn.lock b/yarn.lock
index ed35ec18f1b..2e1f40dd3c5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9797,10 +9797,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-simple-git@^2.8.0:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.8.0.tgz#c8ebda4a16b57c9f774a62df62cb74cfd2c4f3d5"
- integrity sha512-0iXwizUaanqdjn9IpboozWN2opA7jl1JZzeQEePyFXRUGOtwVuSgkMGXLnd7Toa7jqV+uZ1VnDZlCBxxSEk1Dw==
+simple-git@^2.9.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.9.0.tgz#060f87e2d81235f01200d4596b3397a458d76fbe"
+ integrity sha512-rDnsMqvvk2pF7+ID8v7GtzdaXlCJfz1qFIuiQ8fcmCaqm7MITXoOx294ymSzMP0D7IC27kA5WLskkl4ZpauYNQ==
dependencies:
"@kwsites/file-exists" "^1.1.1"
debug "^4.1.1"
From de5ef6af19dc85a4d15e9c7b5ffc0948f1352e67 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Tue, 23 Jun 2020 18:11:26 +0000
Subject: [PATCH 70/71] chore(deps-dev): bump @types/lodash from 4.14.155 to
4.14.156 (#2942)
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 21db5e23e1b..2bb57daaa43 100644
--- a/package.json
+++ b/package.json
@@ -66,7 +66,7 @@
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/jest": "^26.0.0",
"@types/jsdom": "^16.2.3",
- "@types/lodash": "^4.14.155",
+ "@types/lodash": "^4.14.156",
"@types/make-dir": "^2.1.0",
"@types/moment": "^2.13.0",
"@types/puppeteer": "^3.0.0",
diff --git a/yarn.lock b/yarn.lock
index 2e1f40dd3c5..fa9fd697813 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1109,10 +1109,10 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
-"@types/lodash@^4.14.155":
- version "4.14.155"
- resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.155.tgz#e2b4514f46a261fd11542e47519c20ebce7bc23a"
- integrity sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg==
+"@types/lodash@^4.14.156":
+ version "4.14.156"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.156.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1"
+ integrity sha512-l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8lQ==
"@types/make-dir@^2.1.0":
version "2.1.0"
From 23db22fb357a9ce47557db9b2300418a696e549e Mon Sep 17 00:00:00 2001
From: Dan Bjorge
Date: Tue, 23 Jun 2020 11:12:53 -0700
Subject: [PATCH 71/71] feat(android-setup): choose host port dynamically
(#2933)
This PR uses the portfinder NPM package to have our service configurator dynamically choose a free host port to bind to, rather than unilaterally choosing the same port hardcoded into the service.
---
package.json | 1 +
.../flux/store/android-setup-store.ts | 1 +
.../android-setup-state-machine-types.ts | 1 +
.../android/android-service-configurator.ts | 4 +-
.../appium-service-configurator-factory.ts | 8 +-
.../android/appium-service-configurator.ts | 26 ++-
.../android/setup/android-setup-deps.ts | 3 +-
.../android/setup/live-android-setup-deps.ts | 8 +-
.../steps/configuring-port-forwarding.ts | 12 +-
src/electron/views/renderer-initializer.ts | 7 +-
...ppium-service-configurator-factory.test.ts | 23 ++-
.../appium-service-configurator.test.ts | 157 ++++++++++-----
.../setup/live-android-setup-deps.test.ts | 74 +++++--
.../steps/configuring-port-forwarding.test.ts | 190 +++++++++++++-----
yarn.lock | 13 +-
15 files changed, 388 insertions(+), 140 deletions(-)
diff --git a/package.json b/package.json
index 2bb57daaa43..f676e631c7f 100644
--- a/package.json
+++ b/package.json
@@ -151,6 +151,7 @@
"lodash": "^4.17.15",
"moment": "^2.27.0",
"office-ui-fabric-react": "7.98.0",
+ "portfinder": "^1.0.26",
"q": "1.5.1",
"react": "^16.13.1",
"react-copy-to-clipboard": "^5.0.2",
diff --git a/src/electron/flux/store/android-setup-store.ts b/src/electron/flux/store/android-setup-store.ts
index 4a076a74d1e..b7c2795d18b 100644
--- a/src/electron/flux/store/android-setup-store.ts
+++ b/src/electron/flux/store/android-setup-store.ts
@@ -28,6 +28,7 @@ export class AndroidSetupStore extends BaseStoreImpl {
stepTransition: this.stepTransition,
setSelectedDevice: this.setSelectedDevice,
setAvailableDevices: this.setAvailableDevices,
+ getScanPort: () => this.state.scanPort,
setScanPort: this.setScanPort,
setApplicationName: this.setApplicationName,
});
diff --git a/src/electron/flux/types/android-setup-state-machine-types.ts b/src/electron/flux/types/android-setup-state-machine-types.ts
index b0df58a14fb..088fddaeada 100644
--- a/src/electron/flux/types/android-setup-state-machine-types.ts
+++ b/src/electron/flux/types/android-setup-state-machine-types.ts
@@ -14,6 +14,7 @@ export type AndroidSetupStoreCallbacks = {
stepTransition: AndroidSetupStepTransitionCallback;
setSelectedDevice: (device: DeviceInfo) => void;
setAvailableDevices: (devices: DeviceInfo[]) => void;
+ getScanPort: () => number | null;
setScanPort: (scanPort?: number) => void;
setApplicationName: (appName?: string) => void;
};
diff --git a/src/electron/platform/android/android-service-configurator.ts b/src/electron/platform/android/android-service-configurator.ts
index 4659cb2fef1..b3c9057b707 100644
--- a/src/electron/platform/android/android-service-configurator.ts
+++ b/src/electron/platform/android/android-service-configurator.ts
@@ -22,8 +22,8 @@ export interface AndroidServiceConfigurator {
getPermissionInfo(deviceId: string): Promise;
installService(deviceId: string): Promise;
uninstallService(deviceId: string): Promise;
- setTcpForwarding(deviceId: string): Promise;
- removeTcpForwarding(deviceId: string): Promise;
+ setupTcpForwarding(deviceId: string): Promise;
+ removeTcpForwarding(deviceId: string, hostPort: number): Promise;
}
export interface AndroidServiceConfiguratorFactory {
diff --git a/src/electron/platform/android/appium-service-configurator-factory.ts b/src/electron/platform/android/appium-service-configurator-factory.ts
index 383e9615085..84e7329c69a 100644
--- a/src/electron/platform/android/appium-service-configurator-factory.ts
+++ b/src/electron/platform/android/appium-service-configurator-factory.ts
@@ -11,12 +11,16 @@ import {
AppiumAdbCreateParameters,
AppiumAdbCreator,
} from 'electron/platform/android/appium-adb-creator';
-import { AppiumServiceConfigurator } from 'electron/platform/android/appium-service-configurator';
+import {
+ AppiumServiceConfigurator,
+ PortFinder,
+} from 'electron/platform/android/appium-service-configurator';
export class AppiumServiceConfiguratorFactory implements AndroidServiceConfiguratorFactory {
public constructor(
private readonly adbCreator: AppiumAdbCreator,
private readonly apkLocator: AndroidServiceApkLocator,
+ private readonly portFinder: PortFinder,
) {}
public getServiceConfigurator = async (
@@ -30,6 +34,6 @@ export class AppiumServiceConfiguratorFactory implements AndroidServiceConfigura
const adb: ADB = await this.adbCreator.createADB(parameters);
- return new AppiumServiceConfigurator(adb, this.apkLocator);
+ return new AppiumServiceConfigurator(adb, this.apkLocator, this.portFinder);
};
}
diff --git a/src/electron/platform/android/appium-service-configurator.ts b/src/electron/platform/android/appium-service-configurator.ts
index ef2c6dee1e1..0938975c78f 100644
--- a/src/electron/platform/android/appium-service-configurator.ts
+++ b/src/electron/platform/android/appium-service-configurator.ts
@@ -9,17 +9,24 @@ import {
PackageInfo,
PermissionInfo,
} from 'electron/platform/android/android-service-configurator';
+import { PortFinderOptions } from 'portfinder';
import { DictionaryStringTo } from 'types/common-types';
type AdbDevice = {
udid: string;
};
+export type PortFinder = (options?: PortFinderOptions) => Promise;
+
const servicePackageName: string = 'com.microsoft.accessibilityinsightsforandroidservice';
+export const servicePortNumber: number = 62442; // hardcoded in service APK
-export const defaultAdbPortNumber: number = 62442;
export class AppiumServiceConfigurator implements AndroidServiceConfigurator {
- constructor(private readonly adb: ADB, private readonly apkLocator: AndroidServiceApkLocator) {}
+ constructor(
+ private readonly adb: ADB,
+ private readonly apkLocator: AndroidServiceApkLocator,
+ private readonly portFinder: PortFinder,
+ ) {}
public getConnectedDevices = async (): Promise> => {
const detectedDevices: DictionaryStringTo = {};
@@ -82,14 +89,19 @@ export class AppiumServiceConfigurator implements AndroidServiceConfigurator {
await this.adb.uninstallApk(servicePackageName);
};
- public setTcpForwarding = async (deviceId: string): Promise => {
+ public setupTcpForwarding = async (deviceId: string): Promise => {
+ const hostPort = await this.portFinder({
+ port: servicePortNumber,
+ stopPort: servicePortNumber + 100,
+ });
+
this.adb.setDeviceId(deviceId);
- await this.adb.forwardPort(defaultAdbPortNumber, defaultAdbPortNumber);
- return defaultAdbPortNumber;
+ await this.adb.forwardPort(hostPort, servicePortNumber);
+ return hostPort;
};
- public removeTcpForwarding = async (deviceId: string): Promise => {
+ public removeTcpForwarding = async (deviceId: string, hostPort: number): Promise => {
this.adb.setDeviceId(deviceId);
- await this.adb.removePortForward(defaultAdbPortNumber);
+ await this.adb.removePortForward(hostPort);
};
}
diff --git a/src/electron/platform/android/setup/android-setup-deps.ts b/src/electron/platform/android/setup/android-setup-deps.ts
index dc105537238..3aef6082a09 100644
--- a/src/electron/platform/android/setup/android-setup-deps.ts
+++ b/src/electron/platform/android/setup/android-setup-deps.ts
@@ -12,7 +12,8 @@ export type AndroidSetupDeps = {
hasExpectedServiceVersion: () => Promise;
installService: () => Promise;
hasExpectedPermissions: () => Promise;
- setTcpForwarding: () => Promise;
+ setupTcpForwarding: () => Promise;
+ removeTcpForwarding: (hostPort: number) => Promise;
getApplicationName: () => Promise;
logger: Logger;
};
diff --git a/src/electron/platform/android/setup/live-android-setup-deps.ts b/src/electron/platform/android/setup/live-android-setup-deps.ts
index 2c05039ccc6..86b9c20ac2c 100644
--- a/src/electron/platform/android/setup/live-android-setup-deps.ts
+++ b/src/electron/platform/android/setup/live-android-setup-deps.ts
@@ -93,8 +93,12 @@ export class LiveAndroidSetupDeps implements AndroidSetupDeps {
return false;
};
- public setTcpForwarding = async (): Promise => {
- return await this.serviceConfig.setTcpForwarding(this.selectedDeviceId);
+ public setupTcpForwarding = async (): Promise => {
+ return await this.serviceConfig.setupTcpForwarding(this.selectedDeviceId);
+ };
+
+ public removeTcpForwarding = async (hostPort: number): Promise => {
+ return await this.serviceConfig.removeTcpForwarding(this.selectedDeviceId, hostPort);
};
public getApplicationName = async (): Promise => {
diff --git a/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts b/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
index 904d143d713..f44bfd5d332 100644
--- a/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
+++ b/src/electron/platform/android/setup/steps/configuring-port-forwarding.ts
@@ -7,9 +7,15 @@ export const configuringPortForwarding: AndroidSetupStepConfig = deps => ({
actions: {},
onEnter: async () => {
try {
- deps.setScanPort(null);
- deps.setApplicationName(null);
- const hostPort = await deps.setTcpForwarding();
+ const existingPort = deps.getScanPort();
+ if (existingPort != null) {
+ deps.logger.log(`removing old tcp:${existingPort} forwarding`);
+ await deps.removeTcpForwarding(existingPort);
+ deps.setScanPort(null);
+ deps.setApplicationName(null);
+ }
+
+ const hostPort = await deps.setupTcpForwarding();
deps.logger.log(`configured forwarding to tcp:${hostPort}`);
const appName = await deps.getApplicationName();
diff --git a/src/electron/views/renderer-initializer.ts b/src/electron/views/renderer-initializer.ts
index 38356c0aa5b..1c4426cc60f 100644
--- a/src/electron/views/renderer-initializer.ts
+++ b/src/electron/views/renderer-initializer.ts
@@ -94,6 +94,7 @@ import { PlainTextFormatter } from 'issue-filing/common/markup/plain-text-format
import { IssueFilingServiceProviderForUnifiedImpl } from 'issue-filing/issue-filing-service-provider-for-unified-impl';
import { UnifiedResultToIssueFilingDataConverter } from 'issue-filing/unified-result-to-issue-filing-data';
import { loadTheme, setFocusVisibility } from 'office-ui-fabric-react';
+import { getPortPromise } from 'portfinder';
import * as ReactDOM from 'react-dom';
import { ReportExportServiceProviderImpl } from 'report-export/report-export-service-provider-impl';
import { getDefaultAddListenerForCollapsibleSection } from 'reports/components/report-sections/collapsible-script-provider';
@@ -204,7 +205,11 @@ getPersistedData(indexedDBInstance, indexedDBDataKeysToFetch).then(
androidSetupActions,
createAndroidSetupStateMachineFactory(
new LiveAndroidSetupDeps(
- new AppiumServiceConfiguratorFactory(new LiveAppiumAdbCreator(), apkLocator),
+ new AppiumServiceConfiguratorFactory(
+ new LiveAppiumAdbCreator(),
+ apkLocator,
+ getPortPromise,
+ ),
userConfigurationStore,
apkLocator,
userConfigMessageCreator,
diff --git a/src/tests/unit/tests/electron/platform/android/appium-service-configurator-factory.test.ts b/src/tests/unit/tests/electron/platform/android/appium-service-configurator-factory.test.ts
index f050e77aabe..67995a6a1c3 100644
--- a/src/tests/unit/tests/electron/platform/android/appium-service-configurator-factory.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/appium-service-configurator-factory.test.ts
@@ -3,17 +3,22 @@
import { AndroidServiceApkLocator } from 'electron/platform/android/android-service-apk-locator';
import { AppiumAdbCreator } from 'electron/platform/android/appium-adb-creator';
-import { AppiumServiceConfigurator } from 'electron/platform/android/appium-service-configurator';
+import {
+ AppiumServiceConfigurator,
+ PortFinder,
+} from 'electron/platform/android/appium-service-configurator';
import { AppiumServiceConfiguratorFactory } from 'electron/platform/android/appium-service-configurator-factory';
import { IMock, Mock, MockBehavior, Times } from 'typemoq';
describe('AppiumServiceConfiguratorFactory tests', () => {
let adbCreatorMock: IMock;
let apkLocatorMock: IMock;
+ let portFinderMock: IMock;
beforeEach(() => {
adbCreatorMock = Mock.ofType(undefined, MockBehavior.Strict);
apkLocatorMock = Mock.ofType(undefined, MockBehavior.Strict);
+ portFinderMock = Mock.ofType(undefined, MockBehavior.Strict);
});
it('getServiceConfigurator creates without parameters if no sdkRoot is provided', async () => {
@@ -24,14 +29,14 @@ describe('AppiumServiceConfiguratorFactory tests', () => {
const factory = new AppiumServiceConfiguratorFactory(
adbCreatorMock.object,
apkLocatorMock.object,
+ portFinderMock.object,
);
expect(await factory.getServiceConfigurator(null)).toBeInstanceOf(
AppiumServiceConfigurator,
);
- adbCreatorMock.verifyAll();
- apkLocatorMock.verifyAll();
+ verifyAllMocks();
});
it('getServiceConfigurator creates with sdkRoot if it is provided', async () => {
@@ -43,14 +48,14 @@ describe('AppiumServiceConfiguratorFactory tests', () => {
const factory = new AppiumServiceConfiguratorFactory(
adbCreatorMock.object,
apkLocatorMock.object,
+ portFinderMock.object,
);
expect(await factory.getServiceConfigurator(expectedSdkRoot)).toBeInstanceOf(
AppiumServiceConfigurator,
);
- adbCreatorMock.verifyAll();
- apkLocatorMock.verifyAll();
+ verifyAllMocks();
});
it('getServiceConfigurator propagates error to caller', async () => {
@@ -62,11 +67,17 @@ describe('AppiumServiceConfiguratorFactory tests', () => {
const factory = new AppiumServiceConfiguratorFactory(
adbCreatorMock.object,
apkLocatorMock.object,
+ portFinderMock.object,
);
await expect(factory.getServiceConfigurator(null)).rejects.toThrowError(expectedMessage);
+ verifyAllMocks();
+ });
+
+ function verifyAllMocks(): void {
adbCreatorMock.verifyAll();
apkLocatorMock.verifyAll();
- });
+ portFinderMock.verifyAll();
+ }
});
diff --git a/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts b/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts
index 229f8fc6153..e3836630cb8 100644
--- a/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/appium-service-configurator.test.ts
@@ -10,12 +10,16 @@ import {
PackageInfo,
PermissionInfo,
} from 'electron/platform/android/android-service-configurator';
-import { AppiumServiceConfigurator } from 'electron/platform/android/appium-service-configurator';
-import { IMock, Mock, MockBehavior, Times } from 'typemoq';
+import {
+ AppiumServiceConfigurator,
+ PortFinder,
+} from 'electron/platform/android/appium-service-configurator';
+import { IMock, It, Mock, MockBehavior, Times } from 'typemoq';
describe('AppiumServiceConfigurator tests', () => {
let adbMock: IMock;
let apkLocatorMock: IMock;
+ let portFinderMock: IMock;
let testSubject: AppiumServiceConfigurator;
const emulatorId: string = 'id1';
@@ -26,12 +30,19 @@ describe('AppiumServiceConfigurator tests', () => {
const dumpsysAccessibilitySnippetWithServiceRunning: string =
'Service[label=Accessibility Insights for';
const expectedPathToApk: string = './some/path/package.apk';
- const expectedPortNumber: number = 62442;
+ const expectedServicePortNumber: number = 62442;
+ const expectedHostPortRangeStart: number = 62442;
+ const expectedHostPortRangeStop: number = 62542;
beforeEach(() => {
adbMock = Mock.ofType(undefined, MockBehavior.Strict);
apkLocatorMock = Mock.ofType(undefined, MockBehavior.Strict);
- testSubject = new AppiumServiceConfigurator(adbMock.object, apkLocatorMock.object);
+ portFinderMock = Mock.ofType(undefined, MockBehavior.Strict);
+ testSubject = new AppiumServiceConfigurator(
+ adbMock.object,
+ apkLocatorMock.object,
+ portFinderMock.object,
+ );
});
it('getConnectedDevices, propagates error', async () => {
@@ -349,57 +360,111 @@ describe('AppiumServiceConfigurator tests', () => {
apkLocatorMock.verifyAll();
});
- it('setTcpForwarding, propagates error', async () => {
- const expectedMessage: string = 'Thrown duriung setTcpForwarding';
- adbMock
- .setup(m => m.setDeviceId(emulatorId))
- .throws(new Error(expectedMessage))
- .verifiable(Times.once());
-
- await expect(testSubject.setTcpForwarding(emulatorId)).rejects.toThrowError(
- expectedMessage,
- );
-
- adbMock.verifyAll();
- apkLocatorMock.verifyAll();
+ describe('setupTcpForwarding', () => {
+ it('propagates error from portFinder', async () => {
+ const expectedMessage: string = 'Thrown from portFinder';
+ portFinderMock
+ .setup(m => m(It.isAny()))
+ .returns(() => Promise.reject(new Error(expectedMessage)))
+ .verifiable(Times.once());
+
+ await expect(testSubject.setupTcpForwarding(emulatorId)).rejects.toThrowError(
+ expectedMessage,
+ );
+
+ portFinderMock.verifyAll();
+ adbMock.verifyAll();
+ apkLocatorMock.verifyAll();
+ });
+
+ it('propagates error from ADB.forwardPort', async () => {
+ const portFinderOutput = 63000;
+ portFinderMock
+ .setup(m =>
+ m({
+ port: expectedHostPortRangeStart,
+ stopPort: expectedHostPortRangeStop,
+ }),
+ )
+ .returns(() => Promise.resolve(portFinderOutput))
+ .verifiable(Times.once());
+
+ adbMock.setup(m => m.setDeviceId(emulatorId)).verifiable(Times.once());
+
+ const expectedMessage: string = 'Thrown during forwardPort';
+ adbMock
+ .setup(m => m.forwardPort(portFinderOutput, expectedServicePortNumber))
+ .returns(() => Promise.reject(new Error(expectedMessage)))
+ .verifiable(Times.once());
+
+ await expect(testSubject.setupTcpForwarding(emulatorId)).rejects.toThrowError(
+ expectedMessage,
+ );
+
+ portFinderMock.verifyAll();
+ adbMock.verifyAll();
+ apkLocatorMock.verifyAll();
+ });
+
+ it('invokes ADB.forwardPort using the port from portFinder', async () => {
+ const portFinderOutput = 63000;
+ portFinderMock
+ .setup(m =>
+ m({
+ port: expectedHostPortRangeStart,
+ stopPort: expectedHostPortRangeStop,
+ }),
+ )
+ .returns(() => Promise.resolve(portFinderOutput))
+ .verifiable(Times.once());
+
+ adbMock.setup(m => m.setDeviceId(emulatorId)).verifiable(Times.once());
+ adbMock
+ .setup(m => m.forwardPort(portFinderOutput, expectedServicePortNumber))
+ .verifiable(Times.once());
+
+ const output = await testSubject.setupTcpForwarding(emulatorId);
+ expect(output).toBe(portFinderOutput);
+
+ portFinderMock.verifyAll();
+ adbMock.verifyAll();
+ apkLocatorMock.verifyAll();
+ });
});
- it('setTcpForwarding, succeeds', async () => {
- adbMock.setup(m => m.setDeviceId(emulatorId)).verifiable(Times.once());
- adbMock
- .setup(m => m.forwardPort(expectedPortNumber, expectedPortNumber))
- .verifiable(Times.once());
+ describe('removeTcpForwarding', () => {
+ it('calls ADB.removePortForward using hostPort', async () => {
+ const expectedHostPort = 123;
- const output = await testSubject.setTcpForwarding(emulatorId);
- expect(output).toBe(expectedPortNumber);
+ adbMock.setup(m => m.setDeviceId(emulatorId)).verifiable(Times.once());
+ adbMock
+ .setup(m => m.removePortForward(expectedHostPort))
+ .returns(() => Promise.resolve())
+ .verifiable(Times.once());
- adbMock.verifyAll();
- apkLocatorMock.verifyAll();
- });
+ await testSubject.removeTcpForwarding(emulatorId, expectedHostPort);
- it('removeTcpForwarding, propagates error', async () => {
- const expectedMessage: string = 'Thrown during removeTcpForwarding';
- adbMock
- .setup(m => m.setDeviceId(emulatorId))
- .throws(new Error(expectedMessage))
- .verifiable(Times.once());
+ adbMock.verifyAll();
+ apkLocatorMock.verifyAll();
+ });
- await expect(testSubject.removeTcpForwarding(emulatorId)).rejects.toThrowError(
- expectedMessage,
- );
+ it('propagates error from removePortForward', async () => {
+ const irrelevantHostPort = 123;
+ const expectedMessage: string = 'Thrown during removeTcpForwarding';
- adbMock.verifyAll();
- apkLocatorMock.verifyAll();
- });
+ adbMock.setup(m => m.setDeviceId(emulatorId)).verifiable(Times.once());
+ adbMock
+ .setup(m => m.removePortForward(It.isAny()))
+ .returns(() => Promise.reject(new Error(expectedMessage)))
+ .verifiable(Times.once());
- it('removeTcpForwarding, succeeds', async () => {
- adbMock.setup(m => m.setDeviceId(emulatorId)).verifiable(Times.once());
- adbMock.setup(m => m.removePortForward(expectedPortNumber)).verifiable(Times.once());
+ await expect(
+ testSubject.removeTcpForwarding(emulatorId, irrelevantHostPort),
+ ).rejects.toThrowError(expectedMessage);
- await testSubject.removeTcpForwarding(emulatorId);
-
- adbMock.verifyAll();
- apkLocatorMock.verifyAll();
+ adbMock.verifyAll();
+ apkLocatorMock.verifyAll();
+ });
});
/*
// For live testing, set ANDROID_HOME or ANDROID_SDK_ROOT to point
diff --git a/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
index ba385ce91c7..73118604373 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/live-android-setup-deps.test.ts
@@ -409,56 +409,90 @@ describe('LiveAndroidSetupDeps', () => {
verifyAllMocks();
});
- it('setTcpForwarding propagates error from serviceConfig.setTcpForwarding', async () => {
+ it('setupTcpForwarding propagates error from serviceConfig.setupTcpForwarding', async () => {
const deviceId = 'id1';
const serviceConfigErrorMessage = 'error from serviceConfig';
serviceConfigMock
- .setup(m => m.setTcpForwarding(deviceId))
+ .setup(m => m.setupTcpForwarding(deviceId))
.returns(() => Promise.reject(new Error(serviceConfigErrorMessage)))
.verifiable(Times.once());
await initializeServiceConfig();
testSubject.setSelectedDeviceId(deviceId);
- await expect(testSubject.setTcpForwarding()).rejects.toThrowError(
+ await expect(testSubject.setupTcpForwarding()).rejects.toThrowError(
serviceConfigErrorMessage,
);
verifyAllMocks();
});
- it('getApplicationName returns app name when successful', async () => {
- const config: DeviceConfig = {
- appIdentifier: 'Wonderful App',
- } as DeviceConfig;
+ it('setupTcpForwarding propagates output from serviceConfig.setupTcpForwarding', async () => {
+ const deviceId = 'id1';
+ const serviceConfigOutput = 63000;
+ serviceConfigMock
+ .setup(m => m.setupTcpForwarding(deviceId))
+ .returns(() => Promise.resolve(serviceConfigOutput))
+ .verifiable(Times.once());
+ await initializeServiceConfig();
- const p = new Promise(resolve => resolve(config));
+ testSubject.setSelectedDeviceId(deviceId);
+ const output = await testSubject.setupTcpForwarding();
- fetchConfigMock
- .setup(m => m(62442))
- .returns(() => p)
- .verifiable();
+ expect(output).toBe(serviceConfigOutput);
- const appName = await testSubject.getApplicationName();
+ verifyAllMocks();
+ });
- expect(appName).toEqual(config.appIdentifier);
+ it('removeTcpForwarding propagates error from serviceConfig.removeTcpForwarding', async () => {
+ const deviceId = 'id1';
+ const port = 2;
+ const serviceConfigErrorMessage = 'error from serviceConfig';
+ serviceConfigMock
+ .setup(m => m.removeTcpForwarding(deviceId, port))
+ .returns(() => Promise.reject(new Error(serviceConfigErrorMessage)))
+ .verifiable(Times.once());
+
+ await initializeServiceConfig();
+
+ testSubject.setSelectedDeviceId(deviceId);
+ await expect(testSubject.removeTcpForwarding(port)).rejects.toThrowError(
+ serviceConfigErrorMessage,
+ );
verifyAllMocks();
});
- it('setTcpForwarding propagates output from serviceConfig.setTcpForwarding', async () => {
+ it('removeTcpForwarding propagates to serviceConfig.removeTcpForwarding', async () => {
const deviceId = 'id1';
- const serviceConfigOutput = 63000;
+ const port = 63000;
serviceConfigMock
- .setup(m => m.setTcpForwarding(deviceId))
- .returns(() => Promise.resolve(serviceConfigOutput))
+ .setup(m => m.removeTcpForwarding(deviceId, port))
+ .returns(() => Promise.resolve())
.verifiable(Times.once());
await initializeServiceConfig();
testSubject.setSelectedDeviceId(deviceId);
- const output = await testSubject.setTcpForwarding();
+ await testSubject.removeTcpForwarding(port);
- expect(output).toBe(serviceConfigOutput);
+ verifyAllMocks();
+ });
+
+ it('getApplicationName returns app name when successful', async () => {
+ const config: DeviceConfig = {
+ appIdentifier: 'Wonderful App',
+ } as DeviceConfig;
+
+ const p = new Promise(resolve => resolve(config));
+
+ fetchConfigMock
+ .setup(m => m(62442))
+ .returns(() => p)
+ .verifiable();
+
+ const appName = await testSubject.getApplicationName();
+
+ expect(appName).toEqual(config.appIdentifier);
verifyAllMocks();
});
diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
index 0569ca3e5af..95454847fad 100644
--- a/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
+++ b/src/tests/unit/tests/electron/platform/android/setup/steps/configuring-port-forwarding.test.ts
@@ -11,13 +11,6 @@ describe('Android setup step: configuringPortForwarding', () => {
scanPort?: number;
};
- beforeEach(() => {
- mockStoreState = {
- appName: null,
- scanPort: null,
- };
- });
-
it('has expected properties', () => {
const deps = {} as AndroidSetupStepConfigDeps;
const step = configuringPortForwarding(deps);
@@ -26,13 +19,17 @@ describe('Android setup step: configuringPortForwarding', () => {
});
it('onEnter transitions to prompt-connected-start-testing with state set on success', async () => {
- const scanPort = 63000;
- const appName = 'my app name';
+ const scanPort = 2;
+ const appName = 'new app';
+ mockStoreState = {
+ appName: null,
+ scanPort: null,
+ };
const depsMock = makeMockDepsForMockStore();
depsMock
- .setup(m => m.setTcpForwarding())
+ .setup(m => m.setupTcpForwarding())
.returns(() => Promise.resolve(scanPort))
.verifiable(Times.once());
@@ -51,46 +48,62 @@ describe('Android setup step: configuringPortForwarding', () => {
depsMock.verifyAll();
});
- it('onEnter transitions to prompt-configuring-port-forwarding-failed with null state on setTcpForwarding failure', async () => {
+ it.each`
+ caseName | startingAppName | startingScanPort
+ ${'without previous state'} | ${null} | ${null}
+ ${'with previous state'} | ${'old app'} | ${1}
+ `(
+ 'onEnter clears previous forwarding, then transitions to prompt-connected-start-testing with state set on success',
+ async ({ startingAppName, startingScanPort }) => {
+ const newScanPort = 2;
+ const newAppName = 'new app';
+ mockStoreState = {
+ appName: startingAppName,
+ scanPort: startingScanPort,
+ };
+ const depsMock = makeMockDepsForMockStore();
+
+ depsMock
+ .setup(m => m.removeTcpForwarding(startingScanPort))
+ .returns(() => Promise.resolve())
+ .verifiable(startingScanPort === null ? Times.never() : Times.once());
+
+ depsMock
+ .setup(m => m.setupTcpForwarding())
+ .returns(() => Promise.resolve(newScanPort))
+ .verifiable(Times.once());
+
+ depsMock
+ .setup(m => m.getApplicationName())
+ .returns(_ => Promise.resolve(newAppName))
+ .verifiable(Times.once());
+
+ depsMock.setup(m => m.stepTransition('prompt-connected-start-testing'));
+
+ const step = configuringPortForwarding(depsMock.object);
+ await step.onEnter();
+
+ expect(mockStoreState.appName).toBe(newAppName);
+ expect(mockStoreState.scanPort).toBe(newScanPort);
+ depsMock.verifyAll();
+ },
+ );
+
+ it('onEnter (with previous state) transitions to prompt-configuring-port-forwarding-failed with old state on removeTcpForwarding failure', async () => {
+ const startingAppName = 'old app';
+ const startingScanPort = 1;
mockStoreState = {
- appName: 'old name which should get cleared on failure',
- scanPort: 1,
+ appName: 'old app',
+ scanPort: startingScanPort,
};
const depsMock = makeMockDepsForMockStore();
depsMock
- .setup(m => m.setTcpForwarding())
- .returns(() => Promise.reject(new Error('test error')))
+ .setup(m => m.removeTcpForwarding(startingScanPort))
+ .returns(() => Promise.reject(new Error('error from removeTcpForwarding')))
.verifiable(Times.once());
- depsMock
- .setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
- .verifiable(Times.once());
-
- const step = configuringPortForwarding(depsMock.object);
- await step.onEnter();
-
- expect(mockStoreState.appName).toBeNull();
- expect(mockStoreState.scanPort).toBeNull();
- depsMock.verifyAll();
- });
-
- it('onEnter transitions to prompt-configuring-port-forwarding-failed with null state on getApplicationName failure', async () => {
- mockStoreState = {
- appName: 'old name which should get cleared on failure',
- scanPort: 1,
- };
- const depsMock = makeMockDepsForMockStore();
-
- depsMock
- .setup(m => m.setTcpForwarding())
- .returns(() => Promise.resolve(2))
- .verifiable(Times.once());
-
- depsMock
- .setup(m => m.getApplicationName())
- .returns(() => Promise.reject(new Error('error from getApplicationName')))
- .verifiable(Times.once());
+ depsMock.setup(m => m.setupTcpForwarding()).verifiable(Times.never());
depsMock
.setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
@@ -99,11 +112,88 @@ describe('Android setup step: configuringPortForwarding', () => {
const step = configuringPortForwarding(depsMock.object);
await step.onEnter();
- expect(mockStoreState.appName).toBeNull(); // not 2
- expect(mockStoreState.scanPort).toBeNull();
+ expect(mockStoreState.appName).toBe(startingAppName);
+ expect(mockStoreState.scanPort).toBe(startingScanPort);
depsMock.verifyAll();
});
+ it.each`
+ caseName | startingAppName | startingScanPort
+ ${'without previous state'} | ${null} | ${null}
+ ${'with previous state'} | ${'old app'} | ${1}
+ `(
+ 'onEnter ($caseName) transitions to prompt-configuring-port-forwarding-failed with null state on setupTcpForwarding failure',
+ async ({ startingAppName, startingScanPort }) => {
+ mockStoreState = {
+ appName: startingAppName,
+ scanPort: startingScanPort,
+ };
+ const depsMock = makeMockDepsForMockStore();
+
+ depsMock
+ .setup(m => m.removeTcpForwarding(startingScanPort))
+ .returns(() => Promise.resolve())
+ .verifiable(startingScanPort === null ? Times.never() : Times.once());
+
+ depsMock
+ .setup(m => m.setupTcpForwarding())
+ .returns(() => Promise.reject(new Error('test error')))
+ .verifiable(Times.once());
+
+ depsMock
+ .setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
+ .verifiable(Times.once());
+
+ const step = configuringPortForwarding(depsMock.object);
+ await step.onEnter();
+
+ expect(mockStoreState.appName).toBeNull();
+ expect(mockStoreState.scanPort).toBeNull();
+ depsMock.verifyAll();
+ },
+ );
+
+ it.each`
+ caseName | startingAppName | startingScanPort
+ ${'without previous state'} | ${null} | ${null}
+ ${'with previous state'} | ${'old app'} | ${1}
+ `(
+ 'onEnter ($caseName) transitions to prompt-configuring-port-forwarding-failed with null state on getApplicationName failure',
+ async ({ startingAppName, startingScanPort }) => {
+ mockStoreState = {
+ appName: startingAppName,
+ scanPort: startingScanPort,
+ };
+ const depsMock = makeMockDepsForMockStore();
+
+ depsMock
+ .setup(m => m.removeTcpForwarding(startingScanPort))
+ .returns(() => Promise.resolve())
+ .verifiable(startingScanPort === null ? Times.never() : Times.once());
+
+ depsMock
+ .setup(m => m.setupTcpForwarding())
+ .returns(() => Promise.resolve(2))
+ .verifiable(Times.once());
+
+ depsMock
+ .setup(m => m.getApplicationName())
+ .returns(() => Promise.reject(new Error('error from getApplicationName')))
+ .verifiable(Times.once());
+
+ depsMock
+ .setup(m => m.stepTransition('prompt-configuring-port-forwarding-failed'))
+ .verifiable(Times.once());
+
+ const step = configuringPortForwarding(depsMock.object);
+ await step.onEnter();
+
+ expect(mockStoreState.appName).toBeNull(); // not 2
+ expect(mockStoreState.scanPort).toBeNull();
+ depsMock.verifyAll();
+ },
+ );
+
function makeMockDepsForMockStore(): IMock {
const depsMock = Mock.ofType(undefined, MockBehavior.Strict);
@@ -122,7 +212,12 @@ describe('Android setup step: configuringPortForwarding', () => {
mockStoreState.scanPort = newPort;
})
// We don't care how many times this is invoked, we only care about the final mockStoreState
- .verifiable(Times.atLeastOnce());
+ .verifiable(Times.atLeast(0));
+
+ depsMock
+ .setup(m => m.getScanPort())
+ .returns(() => mockStoreState.scanPort)
+ .verifiable(Times.atLeast(0));
depsMock
.setup(m => m.setApplicationName(It.isAny()))
@@ -130,8 +225,7 @@ describe('Android setup step: configuringPortForwarding', () => {
mockStoreState.appName = newName;
})
// We don't care how many times this is invoked, we only care about the final mockStoreState
-
- .verifiable(Times.atLeastOnce());
+ .verifiable(Times.atLeast(0));
return depsMock;
}
diff --git a/yarn.lock b/yarn.lock
index fa9fd697813..af67025fec9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2037,7 +2037,7 @@ async@0.9.x:
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
-async@^2.0.0, async@^2.6.0, async@^2.6.1, async@^2.6.3:
+async@^2.0.0, async@^2.6.0, async@^2.6.1, async@^2.6.2, async@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
@@ -3484,7 +3484,7 @@ debug@=3.1.0:
dependencies:
ms "2.0.0"
-debug@^3.0.0, debug@^3.1.0, debug@^3.2.6:
+debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -8405,6 +8405,15 @@ pngjs@^5.0.0:
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==
+portfinder@^1.0.26:
+ version "1.0.26"
+ resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
+ integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==
+ dependencies:
+ async "^2.6.2"
+ debug "^3.1.1"
+ mkdirp "^0.5.1"
+
posix-character-classes@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"