* Basic E2E setup for android

* Basic tests working

* Added scrolling element selector to Android

* Cleanup code

* Change files

* Replace ScrollView id with existing const

* Clean up mobile scroll

* Testing Android pipeline

* Fix platform

* Fix spacing

* Changing Gradlew task

* Comment non-android tests

* Changed vm to ubuntu added working directory to gradlew

* Update emulator to use xamarin

* Updated fradlew task

* Revert ubuntu change for Android PR

* Revert "Update emulator to use xamarin"

This reverts commit 6bea0a8ed6.

* Change jdk path

* Update version for jdk

* Disable yarn android

* Revert "Disable yarn android"

This reverts commit 1dc6bad9dc.

* Set to re-install apk mode

* Remove existing packages

* Remove yarn android, add caching for avd

* Added apk dump mechanism

* Fix syntax

* Fix syntax

* Fix syntax

* Update apk dump to run on failure

* Testing screenshot on android

* Update emulator script

* Fix missing label for E2E

* Reverting APK dump mechanism

* Attempting to fix screenshot issue

* Attempting to fix screenshot issue x2

* Attempting to fix screenshot issue x3

* Attempting to fix screenshot issue x4

* Revert "Attempting to fix screenshot issue x4"

This reverts commit f6ed8fd035.

* Change to MacOS 12

* Revert "Change to MacOS 12"

This reverts commit 7cdaacdeba.

* Attempting to fix screenshot issue x5

* Revert "Comment non-android tests"

This reverts commit d4faed2d29.

* Revert "Testing screenshot on android"

This reverts commit 88cde98d61.

* Added apk dump on failure

* Code cleanup

* Test Screenshot

* Change emulator device model and Remove apk dump

* Revert "Test Screenshot"

This reverts commit 3deb82308f.

* Replace testId with testProps

* Attempt AVD Caching

* Fix task blocks

* Fix import

* Revert AVD Caching

* Revert "Revert AVD Caching"

This reverts commit f31ac5ab08.

* Try different path

* Path format fix

* Change path to single folder

* Enable quick boot emulator

* Revert "Enable quick boot emulator"

This reverts commit e50cfa9f0f.

* Removing caching

* Code cleanup

* Resolve comments

* Resolve comments

* Remove extra bundle command from E2E
This commit is contained in:
Ayush Singh 2023-01-02 23:09:50 +05:30 коммит произвёл GitHub
Родитель 2b961837d5
Коммит f077f84f8f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
47 изменённых файлов: 1072 добавлений и 126 удалений

Просмотреть файл

@ -61,14 +61,8 @@ jobs:
# sets-up specifics for android dependency like NDK & emulator
- template: templates/android-dep-setup.yml
- bash: |
echo "yarn $(platform)"
yarn $(platform)
workingDirectory: apps/fluent-tester
displayName: 'yarn $(platform)'
env:
JAVA_HOME: $(JAVA_HOME_11_X64)
PATH: $(JAVA_HOME_11_X64)/bin;$(PATH)
# builds a debug apk and runs E2E tests on it
- template: templates/e2e-testing-android.yml
- job: macOSPR
displayName: macOS PR

Просмотреть файл

@ -7,19 +7,41 @@ steps:
#!/usr/bin/env bash
# Install AVD files
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-27;google_apis;x86'
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-27;default;x86_64'
# Create emulator
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n android_emulator -k 'system-images;android-27;google_apis;x86' --force
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n android_emulator -d 19 --package 'system-images;android-27;default;x86_64'
# list emulator
echo "Available emulator"
$ANDROID_HOME/emulator/emulator -list-avds
if false; then
emulator_config=~/.android/avd/android_emulator.avd/config.ini
# The following is to support empty OR populated config.ini files,
# the state of which is dependant on the version of the emulator used (which we don't control),
# Replace existing config (NOTE we're on MacOS so sed works differently!)
sed -i .bak 's/hw.lcd.density=.*/hw.lcd.density=420/' "$emulator_config"
sed -i .bak 's/hw.lcd.height=.*/hw.lcd.height=1920/' "$emulator_config"
sed -i .bak 's/hw.lcd.width=.*/hw.lcd.width=1080/' "$emulator_config"
# Or, add new config
if ! grep -q "hw.lcd.density" "$emulator_config"; then
echo "hw.lcd.density=420" >> "$emulator_config"
fi
if ! grep -q "hw.lcd.height" "$emulator_config"; then
echo "hw.lcd.height=1920" >> "$emulator_config"
fi
if ! grep -q "hw.lcd.width" "$emulator_config"; then
echo "hw.lcd.width=1080" >> "$emulator_config"
fi
echo "Emulator settings ($emulator_config)"
cat "$emulator_config"
fi
echo "Starting emulator"
# Start emulator in background
nohup $ANDROID_HOME/emulator/emulator -avd android_emulator -no-snapshot > /dev/null 2>&1 &
nohup $ANDROID_HOME/emulator/emulator -avd android_emulator -no-snapshot -no-audio -gpu host -no-boot-anim -qemu -m 2048 > /dev/null 2>&1 &
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
#list online device/emulator

Просмотреть файл

@ -0,0 +1,41 @@
steps:
# Building APK also requires bundling, this is currently already being done as part of main Android PR task.
- task: Gradle@2
displayName: 'gradlew build apk'
inputs:
gradleWrapperFile: 'apps/fluent-tester/android/gradlew'
tasks: 'assembleDebug'
gradleOptions: '-Xmx2g'
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.11'
workingDirectory: apps/fluent-tester/android
- script: |
adb install app-debug.apk
workingDirectory: apps/fluent-tester/android/app/build/outputs/apk/debug
displayName: 'install apk'
# Creates a variable that determines whether the previous build tasks succeeded.
# Usage: We want the tasks that generate reports to run for both passing/failing E2E testing tasks. In order to do so, we need to make
# those reporting tasks run even on when certain previous tasks fail. This variable allows us to differentiate build failures from
# E2E testing failures. Thus, if this variable != "Success", we know the build failed, and to not run the reporting tasks.
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Write-Host "##vso[task.setvariable variable=task.Build.status]Success"
condition: succeeded()
displayName: 'Create success build variable'
- script: |
yarn e2etest:android
workingDirectory: apps/E2E
displayName: 'run E2E Android tests'
condition: succeeded()
- template: e2e-publish-artifacts.yml
parameters:
applicationType: android
platform: 'android'
buildArtifacts: variables['task.Build.status']
directory: $(Build.SourcesDirectory)/apps/E2E

Просмотреть файл

@ -5,6 +5,7 @@
"license": "MIT",
"scripts": {
"build": "fluentui-scripts build",
"e2etest:android": "wdio run wdio.conf.android.js",
"e2etest:ios": "wdio run wdio.conf.ios.js",
"e2etest:macos": "wdio run wdio.conf.macos.js",
"e2etest:windows": "rimraf errorShots/* reports/* && wdio run wdio.conf.windows.js"
@ -40,6 +41,7 @@
"appium-mac2-driver": "1.4.0",
"appium-windows-driver": "2.0.7",
"appium-xcuitest-driver": "4.11.1",
"appium-uiautomator2-driver": "^2.10.2",
"@babel/core": "^7.8.0",
"@babel/runtime": "^7.8.0",
"@fluentui-react-native/focus-zone": "^0.11.18"

Просмотреть файл

@ -17,6 +17,10 @@ class AvatarPageObject extends BasePage {
return By(HOMEPAGE_AVATAR_BUTTON);
}
get _pageButtonName() {
return HOMEPAGE_AVATAR_BUTTON;
}
get _pageName() {
return AVATAR_TESTPAGE;
}

Просмотреть файл

@ -0,0 +1,22 @@
import NavigateAppPage from '../../common/NavigateAppPage';
import AvatarPageObject from '../pages/AvatarPageObject';
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
// Before testing begins, allow up to 60 seconds for app to open
describe('Avatar Testing Initialization', function () {
it('Wait for app load', async () => {
await NavigateAppPage.waitForPageDisplayed(BOOT_APP_TIMEOUT);
await expect(await NavigateAppPage.isPageLoaded()).toBeTruthy(NavigateAppPage.ERRORMESSAGE_APPLOAD);
});
it('Click and navigate to Avatar test page', async () => {
await AvatarPageObject.mobileScrollToComponentButton();
await AvatarPageObject.waitForButtonDisplayed(PAGE_TIMEOUT);
/* Click on component button to navigate to test page */
await NavigateAppPage.clickAndGoToAvatarPage();
await AvatarPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
await expect(await AvatarPageObject.isPageLoaded()).toBeTruthy(AvatarPageObject.ERRORMESSAGE_PAGELOAD);
});
});

Просмотреть файл

@ -63,6 +63,10 @@ class ButtonPageObject extends BasePage {
get _pageButton() {
return By(HOMEPAGE_BUTTON_BUTTON);
}
get _pageButtonName() {
return HOMEPAGE_BUTTON_BUTTON;
}
}
export default new ButtonPageObject();

Просмотреть файл

@ -0,0 +1,22 @@
import NavigateAppPage from '../../common/NavigateAppPage';
import ButtonPageObject from '../pages/ButtonPageObject';
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
// Before testing begins, allow up to 60 seconds for app to open
describe('Button Testing Initialization', function () {
it('Wait for app load', async () => {
await NavigateAppPage.waitForPageDisplayed(BOOT_APP_TIMEOUT);
await expect(await NavigateAppPage.isPageLoaded()).toBeTruthy();
});
it('Click and navigate to Button test page', async () => {
await ButtonPageObject.mobileScrollToComponentButton();
await ButtonPageObject.waitForButtonDisplayed(PAGE_TIMEOUT);
/* Click on component button to navigate to test page */
await NavigateAppPage.clickAndGoToButtonPage();
await ButtonPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
await expect(await ButtonPageObject.isPageLoaded()).toBeTruthy();
});
});

Просмотреть файл

@ -82,6 +82,10 @@ class ExperimentalCheckboxPageObject extends BasePage {
get _pageButton() {
return By(HOMEPAGE_CHECKBOX_EXPERIMENTAL_BUTTON);
}
get _pageButtonName() {
return HOMEPAGE_CHECKBOX_EXPERIMENTAL_BUTTON;
}
}
export default new ExperimentalCheckboxPageObject();

Просмотреть файл

@ -0,0 +1,21 @@
import NavigateAppPage from '../../common/NavigateAppPage';
import ExperimentalCheckboxPageObject from '../pages/ExperimentalCheckboxPageObject';
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
describe('Experimental Checkbox Testing Initialization', () => {
it('Wait for app load', async () => {
await NavigateAppPage.waitForPageDisplayed(BOOT_APP_TIMEOUT);
await expect(await NavigateAppPage.isPageLoaded()).toBeTruthy(NavigateAppPage.ERRORMESSAGE_APPLOAD);
});
it('Click and navigate to Experimental Checkbox test page', async () => {
await ExperimentalCheckboxPageObject.mobileScrollToComponentButton();
await ExperimentalCheckboxPageObject.waitForButtonDisplayed(PAGE_TIMEOUT);
/* Click on component button to navigate to test page */
await NavigateAppPage.clickAndGoToCheckboxExperimentalPage();
await ExperimentalCheckboxPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
await expect(await ExperimentalCheckboxPageObject.isPageLoaded()).toBeTruthy(ExperimentalCheckboxPageObject.ERRORMESSAGE_PAGELOAD);
});
});

Просмотреть файл

@ -162,7 +162,20 @@ export abstract class BasePage {
}
default:
case MobilePlatform.Android:
// Todo
/* 'mobile: scroll' which is used for iOS, does not support direction option on Android.
* Instead, we use the UiScrollable class to scroll down to the desired view based on its 'description' (accessibilityLabel).
* The first selector tells which container to scroll in, and the other selector tells which component to scroll to. */
await browser.waitUntil(
async () => {
const buttonElementSelector = `new UiScrollable(new UiSelector().description("${TESTPAGE_BUTTONS_SCROLLVIEWER}").scrollable(true)).setMaxSearchSwipes(10).setAsVerticalList().scrollIntoView(new UiSelector().description("${this._pageButtonName}"))`;
const pageButton = await $(`android=${buttonElementSelector}`);
return await pageButton.isDisplayed();
},
{
timeout: this.waitForUiEvent,
timeoutMsg: errorMsg,
},
);
break;
}
}
@ -290,6 +303,12 @@ export abstract class BasePage {
// Returns the name of the test page. Useful for error messages (see above).
abstract get _pageName(): string;
// Returns: String
// Returns the name of the button that navigates to the test page.
get _pageButtonName(): string {
return DUMMY_CHAR;
}
// The scrollviewer containing the list of buttons to navigate to each test page
get _testPageButtonScrollViewer() {
return By(TESTPAGE_BUTTONS_SCROLLVIEWER);

Просмотреть файл

@ -0,0 +1,209 @@
const fs = require('fs');
const defaultWaitForTimeout = 20000;
const defaultConnectionRetryTimeout = 60000;
const jasmineDefaultTimeout = 60000; // 60 seconds for Jasmine test timeout
exports.config = {
runner: 'local', // Where should your test be launched
specs: ['src/**/specs/*.android.ts'],
exclude: [],
maxInstances: 30,
capabilities: [
{
maxInstances: 1, // Maximum number of total parallel running workers.
platformName: 'android',
'appium:appPackage': 'com.microsoft.reacttestapp',
'appium:appActivity': 'MainActivity',
'appium:automationName': 'uiautomator2',
},
],
/*
** ===============================================================================================
** Test Configurations - Define all options that are relevant for the WebdriverIO instance here
** ===============================================================================================
*/
logLevel: 'info', // Level of logging verbosity: trace | debug | info | warn | error | silent
bail: 0, // If you only want to run your tests until a specific amount of tests have failed use bail (default is 0 - don't bail, run all tests).
waitforTimeout: defaultWaitForTimeout, // Default timeout for all waitForXXX commands.
connectionRetryTimeout: defaultConnectionRetryTimeout, // Timeout for any WebDriver request to a driver or grid.
connectionRetryCount: 3, // Maximum count of request retries to the Selenium server.
specFileRetries: 3, // The number of times to retry the entire spec file when it fails as a whole.
port: 4723, // default appium port
services: [
[
'appium',
{
logPath: './reports/',
},
],
],
framework: 'jasmine',
jasmineOpts: {
defaultTimeoutInterval: jasmineDefaultTimeout,
},
reporters: ['spec'],
autoCompileOpts: {
autoCompile: true,
tsNodeOpts: {
files: true,
},
},
/*
** ===================
** Hooks
** ===================
** WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
** it and to build services around it. You can either apply a single function or an array of
** methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
** resolved to continue.
*/
/**
* Gets executed once before all workers get launched.
* @param {Object} config wdio configuration object
* @param {Array.<Object>} capabilities list of capabilities details
*/
//onPrepare: function (config, capabilities) {},
/**
* Gets executed before a worker process is spawned and can be used to initialise specific service
* for that worker as well as modify runtime environments in an async fashion.
* @param {String} cid capability id (e.g 0-0)
* @param {[type]} caps object containing capabilities for session that will be spawn in the worker
* @param {[type]} specs specs to be run in the worker process
* @param {[type]} args object that will be merged with the main configuration once worker is initialised
* @param {[type]} execArgv list of string arguments passed to the worker process
*/
// onWorkerStart: function (cid, caps, specs, args, execArgv) {
// },
/**
* Gets executed just before initialising the webdriver session and test framework. It allows you
* to manipulate configurations depending on the capability or spec.
* @param {Object} config wdio configuration object
* @param {Array.<Object>} capabilities list of capabilities details
* @param {Array.<String>} specs List of spec file paths that are to be run
*/
beforeSession: function (/*config, capabilities, specs*/) {
fs.mkdirSync('./errorShots', { recursive: true });
process.env['E2ETEST_PLATFORM'] = 'android';
},
/**
* Gets executed before test execution begins. At this point you can access to all global
* variables like `browser`. It is the perfect place to define custom commands.
* @param {Array.<Object>} capabilities list of capabilities details
* @param {Array.<String>} specs List of spec file paths that are to be run
*/
// before: function () {
// },
/**
* Runs before a WebdriverIO command gets executed.
* @param {String} commandName hook command name
* @param {Array} args arguments that command would receive
*/
// beforeCommand: function (commandName, args) {
// },
/**
* Hook that gets executed before the suite starts
* @param {Object} suite suite details
*/
// beforeSuite: async function () {
// },
/**
* Function to be executed before a test (in Mocha/Jasmine) starts.
*/
// beforeTest: function (test, context) {
// },
/**
* Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
* beforeEach in Mocha)
*/
// beforeHook: function (test, context) {
// },
/**
* Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
* afterEach in Mocha)
*/
// afterHook: function (test, context, { error, result, duration, passed, retries }) {
// },
/**
* Function to be executed after a test (in Mocha/Jasmine).
*/
afterTest: function (test, context, results) {
const resultString = results.passed ? 'Passed' : 'Failed';
console.log('\n Test Case: ' + test.description + '. Result: ' + resultString + '\n');
// if test passed, ignore, else take and save screenshot. Unless it's the first test that boots the app,
// it may be useful to have a screenshot of the app on load.
if (results.passed) {
return;
}
// get current test title and clean it, to use it as file name
const fileName = encodeURIComponent(test.description.replace(/\s+/g, '-'));
// build file path
const filePath = './errorShots/' + fileName + '.png';
// save screenshot
browser.saveScreenshot(filePath);
},
/**
* Hook that gets executed after the suite has ended
* @param {Object} suite suite details
*/
// afterSuite: function (suite) {
// },
/**
* Runs after a WebdriverIO command gets executed
* @param {String} commandName hook command name
* @param {Array} args arguments that command would receive
* @param {Number} result 0 - command success, 1 - command error
* @param {Object} error error object if any
*/
// afterCommand: function (commandName, args, result, error) {
// },
/**
* Gets executed after all tests are done. You still have access to all global variables from
* the test.
* @param {Number} result 0 - test pass, 1 - test fail
* @param {Array.<Object>} capabilities list of capabilities details
* @param {Array.<String>} specs List of spec file paths that ran
*/
// after: function (result, capabilities, specs) {
// },
/**
* Gets executed right after terminating the webdriver session.
* @param {Object} config wdio configuration object
* @param {Array.<Object>} capabilities list of capabilities details
* @param {Array.<String>} specs List of spec file paths that ran
*/
// afterSession: function (config, capabilities, specs) {
// },
/**
* Gets executed after all workers got shut down and the process is about to exit. An error
* thrown in the onComplete hook will result in the test run failing.
* @param {Object} exitCode 0 - success, 1 - fail
* @param {Object} config wdio configuration object
* @param {Array.<Object>} capabilities list of capabilities details
* @param {<Object>} results object containing test results
*/
// onComplete: function (exitCode, config, capabilities, results) {
// console.log('<<< TESTING FINISHED >>>');
// },
/**
* Gets executed when a refresh happens.
* @param {String} oldSessionId session ID of the old session
* @param {String} newSessionId session ID of the new session
*/
//onReload: function(oldSessionId, newSessionId) {
//}
};

Просмотреть файл

@ -10,6 +10,7 @@ import { useTheme } from '@fluentui-react-native/theme-types';
import { ThemePickers } from './theme/ThemePickers';
import { tests } from './testPages';
import { ROOT_VIEW } from '../../E2E/src/common/consts';
import { testProps } from './TestComponents/Common/TestProps';
// uncomment the below lines to enable message spy
/**
@ -73,7 +74,8 @@ const Header: React.FunctionComponent<HeaderProps> = React.memo((props) => {
style={fluentTesterStyles.testHeader}
variant="heroLargeSemibold"
color={theme.host.palette?.TextEmphasis}
testID={BASE_TESTPAGE}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BASE_TESTPAGE)}
>
FluentUI Tests
</Text>
@ -137,7 +139,11 @@ export const FluentTester: React.FunctionComponent<FluentTesterProps> = (props:
const TestList: React.FunctionComponent = React.memo(() => {
return (
<View style={fluentTesterStyles.testList}>
<ScrollView contentContainerStyle={fluentTesterStyles.testListContainerStyle} testID={TESTPAGE_BUTTONS_SCROLLVIEWER}>
<ScrollView
contentContainerStyle={fluentTesterStyles.testListContainerStyle}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(TESTPAGE_BUTTONS_SCROLLVIEWER)}
>
{sortedTestComponents.map((description, index) => {
return (
<Button
@ -146,7 +152,8 @@ export const FluentTester: React.FunctionComponent<FluentTesterProps> = (props:
disabled={index == selectedTestIndex}
onClick={() => setSelectedTestIndex(index)}
style={fluentTesterStyles.testListItem}
testID={description.testPageButton}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(description.testPageButton)}
// This ref so focus can be set on it when the app mounts in win32. Without this, focus won't be set anywhere.
{...(index === 0 && { componentRef: focusOnMountRef })}
>
@ -164,7 +171,11 @@ export const FluentTester: React.FunctionComponent<FluentTesterProps> = (props:
const MobileTestList: React.FunctionComponent = React.memo(() => {
return (
<View style={{ ...mobileStyles.testList, display: isTestListVisible ? 'flex' : 'none' }}>
<ScrollView contentContainerStyle={fluentTesterStyles.testListContainerStyle}>
<ScrollView
contentContainerStyle={fluentTesterStyles.testListContainerStyle}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(TESTPAGE_BUTTONS_SCROLLVIEWER)}
>
{sortedTestComponents.map((description, index) => {
return (
<View key={index}>
@ -178,9 +189,8 @@ export const FluentTester: React.FunctionComponent<FluentTesterProps> = (props:
}
}}
style={mobileStyles.testListItem}
testID={description.testPageButton}
// Please read http://93days.me/testing-react-native-application/ to understand why we set accessibilityLabel here.
accessibilityLabel={description.testPageButton}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(description.testPageButton)}
>
{description.name}
</Text>
@ -203,7 +213,12 @@ export const FluentTester: React.FunctionComponent<FluentTesterProps> = (props:
return (
// On iOS, the accessible prop must be set to false because iOS does not support nested accessibility elements
<RootView style={themedStyles.root} accessible={Platform.OS !== 'ios'} testID={ROOT_VIEW}>
<RootView
style={themedStyles.root}
accessible={Platform.OS !== 'ios'}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(ROOT_VIEW)}
>
<Header enableSinglePaneView={enableSinglePaneView} enableBackButtonIOS={!onTestListView} onBackButtonPressedIOS={onBackPress} />
<HeaderSeparator />
<View style={fluentTesterStyles.testRoot}>

Просмотреть файл

@ -1,6 +1,7 @@
import { Avatar } from '@fluentui-react-native/avatar';
import * as React from 'react';
import { View } from 'react-native';
import { testProps } from '../Common/TestProps';
import {
AVATAR_ACCESSIBILITY_LABEL,
AVATAR_ACCESSIBILITY_HINT,
@ -13,12 +14,18 @@ export const E2EAvatarTest: React.FunctionComponent = () => {
return (
<View>
<Avatar
testID={AVATAR_TEST_COMPONENT}
accessibilityHint={AVATAR_ACCESSIBILITY_HINT}
accessibilityLabel={AVATAR_ACCESSIBILITY_LABEL}
accessibilityRole={AVATAR_ACCESSIBILITY_ROLE}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(AVATAR_TEST_COMPONENT)}
/>
<Avatar
name="Richard"
badge={{ status: 'available' }}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(AVATAR_SECONDARY_TEST_COMPONENT)}
/>
<Avatar testID={AVATAR_SECONDARY_TEST_COMPONENT} name="Richard" badge={{ status: 'available' }} />
</View>
);
};

Просмотреть файл

@ -1,15 +1,28 @@
import { Badge, PresenceBadge } from '@fluentui-react-native/badge';
import * as React from 'react';
import { View } from 'react-native';
import { testProps } from '../Common/TestProps';
import { BADGE_TEST_COMPONENT, BADGE_SECONDARY_TEST_COMPONENT } from '../../../../E2E/src/Badge/consts';
export const E2EBadgeTest: React.FunctionComponent = () => {
return (
<View>
<Badge testID={BADGE_TEST_COMPONENT} appearance="outline" size="extraLarge" badgeColor="success" shape="square">
<Badge
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BADGE_TEST_COMPONENT)}
appearance="outline"
size="extraLarge"
badgeColor="success"
shape="square"
>
Basic Badge
</Badge>
<PresenceBadge testID={BADGE_SECONDARY_TEST_COMPONENT} status="available" outOfOffice={true} />
<PresenceBadge
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BADGE_SECONDARY_TEST_COMPONENT)}
status="available"
outOfOffice={true}
/>
</View>
);
};

Просмотреть файл

@ -18,6 +18,7 @@ import {
BUTTON_FOCUSABLE_TEST_COMPONENT_LABEL,
} from '../../../../E2E/src/Button/consts';
import { IViewWin32Props } from '@office-iss/react-native-win32';
import { testProps } from '../Common/TestProps';
export const E2EButtonExperimentalTest: React.FunctionComponent = () => {
const [buttonPressed, setButtonPressed] = React.useState(false);
@ -48,30 +49,53 @@ export const E2EButtonExperimentalTest: React.FunctionComponent = () => {
return (
<View>
<Stack style={stackStyle}>
<Button testID={BUTTON_TEST_COMPONENT} onClick={onClick} accessibilityLabel={BUTTON_ACCESSIBILITY_LABEL}>
<Button
onClick={onClick}
accessibilityLabel={BUTTON_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_TEST_COMPONENT)}
>
This is a button for E2E testing
</Button>
<Button testID={BUTTON_NO_A11Y_LABEL_COMPONENT} onClick={onClick} accessibilityRole="menuitem">
<Button
onClick={onClick}
accessibilityRole="menuitem"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_NO_A11Y_LABEL_COMPONENT)}
>
{BUTTON_TEST_COMPONENT_LABEL}
</Button>
<Button
testID={BUTTON_PRESS_TEST_COMPONENT}
onClick={onClick}
accessibilityLabel={BUTTON_PRESS_TEST_COMPONENT_LABEL}
{...keyPressProps}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_PRESS_TEST_COMPONENT)}
>
Press &quot;a&quot; or &quot;b&quot; after focusing this button
</Button>
<Button
testID={BUTTON_FOCUSABLE_TEST_COMPONENT}
onClick={onClick}
accessibilityLabel={BUTTON_FOCUSABLE_TEST_COMPONENT_LABEL}
focusable={false}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_FOCUSABLE_TEST_COMPONENT)}
>
This button isn&apos;t focusable (but isn&apos;t disabled or indeterminate either)
</Button>
{buttonPressed ? <Text testID={BUTTON_ON_PRESS}>Button Pressed</Text> : null}
{keyDetected ? <Text testID={BUTTON_ON_KEY}>Button Key Press detected: {keyDetected}</Text> : null}
{buttonPressed ? (
<Text
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_ON_PRESS)}
>
Button Pressed
</Text>
) : null}
{keyDetected ? (
<Text /* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */ {...testProps(BUTTON_ON_KEY)}>
Button Key Press detected: {keyDetected}
</Text>
) : null}
</Stack>
</View>
);

Просмотреть файл

@ -11,6 +11,7 @@ import {
BUTTON_ACCESSIBILITY_LABEL_DEPRECATED,
BUTTON_TEST_COMPONENT_LABEL_DEPRECATED,
} from '../../../../../E2E/src/Button/consts';
import { testProps } from '../../Common/TestProps';
export const E2EButtonTest_deprecated: React.FunctionComponent = () => {
const [buttonPressed, setButtonPressed] = React.useState(false);
@ -24,12 +25,25 @@ export const E2EButtonTest_deprecated: React.FunctionComponent = () => {
<Stack style={stackStyle}>
<Button
content="This is a button for E2E testing"
testID={BUTTON_TEST_COMPONENT_DEPRECATED}
onClick={onClick}
accessibilityLabel={BUTTON_ACCESSIBILITY_LABEL_DEPRECATED}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_TEST_COMPONENT_DEPRECATED)}
/>
<Button content={BUTTON_TEST_COMPONENT_LABEL_DEPRECATED} testID={BUTTON_NO_A11Y_LABEL_COMPONENT_DEPRECATED} onClick={onClick} />
{buttonPressed ? <Text testID={BUTTON_ON_PRESS_DEPRECATED}>Button Pressed</Text> : null}
<Button
content={BUTTON_TEST_COMPONENT_LABEL_DEPRECATED}
onClick={onClick}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_NO_A11Y_LABEL_COMPONENT_DEPRECATED)}
/>
{buttonPressed ? (
<Text
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_ON_PRESS_DEPRECATED)}
>
Button Pressed
</Text>
) : null}
</Stack>
</View>
);

Просмотреть файл

@ -3,6 +3,7 @@ import { ScreenRect, View } from 'react-native';
import { ButtonV1 as Button, Callout, Text, DismissBehaviors } from '@fluentui/react-native';
import { Switch } from '@fluentui-react-native/switch';
import { BUTTON_TO_OPEN_CALLOUT, CALLOUT_ACCESSIBILITY_LABEL, CALLOUT_TEST_COMPONENT } from '../../../../E2E/src/Callout/consts';
import { testProps } from '../Common/TestProps';
export const E2ECalloutTest: React.FunctionComponent = () => {
const [showCallout, setShowCallout] = React.useState(false);
@ -42,7 +43,11 @@ export const E2ECalloutTest: React.FunctionComponent = () => {
/>
))}
</View>
<Button onClick={toggleShowCallout} testID={BUTTON_TO_OPEN_CALLOUT}>
<Button
onClick={toggleShowCallout}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(BUTTON_TO_OPEN_CALLOUT)}
>
Press for Callout
</Button>
<Text selectable={true}>
@ -53,7 +58,6 @@ export const E2ECalloutTest: React.FunctionComponent = () => {
{showCallout && (
<Callout
testID={CALLOUT_TEST_COMPONENT}
anchorRect={myRect}
onDismiss={onDismissCallout}
onShow={onShowCallout}
@ -61,6 +65,8 @@ export const E2ECalloutTest: React.FunctionComponent = () => {
accessibilityRole="alert"
accessibilityOnShowAnnouncement="Be informed that a customized callout has been opened."
dismissBehaviors={Object.keys(dismissBehaviors).filter((behavior) => dismissBehaviors[behavior]) as DismissBehaviors[]}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(CALLOUT_TEST_COMPONENT)}
>
<View style={{ padding: 20, borderWidth: 2, borderColor: 'black' }}>
<Text>just some text so it does not take focus and is not empty.</Text>

Просмотреть файл

@ -10,6 +10,7 @@ import {
CHECKBOX_ACCESSIBILITY_LABEL,
} from '../../../../E2E/src/Checkbox/consts';
import { Stack } from '@fluentui-react-native/stack';
import { testProps } from '../Common/TestProps';
export const E2ECheckboxTest: React.FunctionComponent = () => {
const [checkboxPressed, setCheckboxPressed] = React.useState(false);
@ -28,11 +29,22 @@ export const E2ECheckboxTest: React.FunctionComponent = () => {
accessibilityLabel={CHECKBOX_ACCESSIBILITY_LABEL}
disabled={false}
label="Testing accessibilityLabel"
testID={CHECKBOX_TEST_COMPONENT}
onChange={onClick}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(CHECKBOX_TEST_COMPONENT)}
/>
<Checkbox label={CHECKBOX_TEST_COMPONENT_LABEL} testID={CHECKBOX_NO_A11Y_LABEL_COMPONENT} />
{checkboxPressed ? <Text testID={CHECKBOX_ON_PRESS}>Checkbox Selected</Text> : null}
<Checkbox
label={CHECKBOX_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(CHECKBOX_NO_A11Y_LABEL_COMPONENT)}
/>
{checkboxPressed ? (
<Text /* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(CHECKBOX_ON_PRESS)}
>
Checkbox Selected
</Text>
) : null}
</Stack>
</View>
);

Просмотреть файл

@ -11,6 +11,7 @@ import {
} from '../../../../E2E/src/CheckboxExperimental/consts';
import { Stack } from '@fluentui-react-native/stack';
import { Text } from '@fluentui/react-native';
import { testProps } from '../Common/TestProps';
export const E2ECheckboxExperimentalTest: React.FunctionComponent = () => {
const [checkboxPressed, setCheckboxPressed] = React.useState(false);
@ -29,11 +30,23 @@ export const E2ECheckboxExperimentalTest: React.FunctionComponent = () => {
accessibilityLabel={EXPERIMENTAL_CHECKBOX_ACCESSIBILITY_LABEL}
disabled={false}
label="Testing accessibilityLabel"
testID={EXPERIMENTAL_CHECKBOX_TEST_COMPONENT}
onChange={onClick}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_CHECKBOX_TEST_COMPONENT)}
/>
<Checkbox label={EXPERIMENTAL_CHECKBOX_TEST_COMPONENT_LABEL} testID={EXPERIMENTAL_CHECKBOX_NO_A11Y_LABEL_COMPONENT} />
{checkboxPressed ? <Text testID={EXPERIMENTAL_CHECKBOX_ON_PRESS}>Checkbox Selected</Text> : null}
<Checkbox
label={EXPERIMENTAL_CHECKBOX_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_CHECKBOX_NO_A11Y_LABEL_COMPONENT)}
/>
{checkboxPressed ? (
<Text
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_CHECKBOX_ON_PRESS)}
>
Checkbox Selected
</Text>
) : null}
</Stack>
</View>
);

Просмотреть файл

@ -1,5 +1,6 @@
import * as React from 'react';
import { Picker } from '@react-native-picker/picker';
import { testProps } from './TestProps';
/*
* The MenuPicker was created because the RN Core Picker was deprecated (preventing us from updating to RN 0.66).
@ -33,14 +34,20 @@ export const MenuPicker: React.FunctionComponent<MenuPickerProps> = (props: Menu
return (
<Picker
testID={testID}
prompt={prompt}
selectedValue={selectedItemKey}
onValueChange={(value: string, index: number) => onChange(value, index)}
style={{ ...style }}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(testID)}
>
{collection.map((item, index) => (
<Picker.Item label={item.label} key={index} value={item.value} testID={item.testID} />
<Picker.Item
label={item.label}
key={index}
value={item.value} /* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(item.testID)}
/>
))}
</Picker>
);

Просмотреть файл

@ -0,0 +1,23 @@
import { Platform } from 'react-native';
// Please read http://93days.me/testing-react-native-application/ to understand why we set accessibilityLabel here.
/**
* The underlying Android test drivers use accessibilityLabel to find elements. However, all other platforms use testID.
* Because of this, we're adding the testProps function that takes in a unique identifier and returns the correct prop based on the platform
* (testID for Win32, Windows, macOS, iOS; accessibilityId for Android).
*
* If explict accessibilityLabel is being used for other platforms, apply testProps after it to override it for Android.
* @param id The string to be used as the test identifier
* @returns an object with the correct test identifier prop based on platform
*/
export function testProps(id) {
return Platform.select({
android: {
accessible: true,
accessibilityLabel: id,
},
default: {
testID: id,
},
});
}

Просмотреть файл

@ -3,6 +3,7 @@ import * as React from 'react';
import { Text, View, Switch } from 'react-native';
import { ButtonV1 as Button, ContextualMenu, ContextualMenuItem, Separator } from '@fluentui/react-native';
import { CONTEXTUALMENUITEM_TEST_COMPONENT, CONTEXTUALMENU_TEST_COMPONENT } from '../../../../E2E/src/ContextualMenu/consts';
import { testProps } from '../Common/TestProps';
export const E2EContextualMenuTest: React.FunctionComponent = () => {
const stdBtnRef = React.useRef(null);
@ -75,7 +76,12 @@ export const E2EContextualMenuTest: React.FunctionComponent = () => {
<Text style={{ color: 'blue' }}>none</Text>
)}
</Text>
<Button onClick={toggleShowContextualMenu} componentRef={stdBtnRef} testID={CONTEXTUALMENU_TEST_COMPONENT}>
<Button
onClick={toggleShowContextualMenu}
componentRef={stdBtnRef}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(CONTEXTUALMENU_TEST_COMPONENT)}
>
Press for ContextualMenu
</Button>
</View>
@ -92,7 +98,12 @@ export const E2EContextualMenuTest: React.FunctionComponent = () => {
shouldFocusOnContainer={focusOnContainer}
isBeakVisible={isBeakVisible}
>
<ContextualMenuItem text="MenuItem 1" itemKey="1" testID={CONTEXTUALMENUITEM_TEST_COMPONENT} />
<ContextualMenuItem
text="MenuItem 1"
itemKey="1"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(CONTEXTUALMENUITEM_TEST_COMPONENT)}
/>
<ContextualMenuItem text="MenuItem 2" itemKey="2" />
<ContextualMenuItem text="Disabled Menu Item" itemKey="3" disabled />
<ContextualMenuItem text="MenuItem 4" itemKey="4" />

Просмотреть файл

@ -17,6 +17,7 @@ import {
FOCUSZONE_DIRECTION_PICKER,
} from '../../../../E2E/src/FocusZone/consts';
import { focusZoneTestStyles, GridButton } from './styles';
import { testProps } from '../Common/TestProps';
export const FocusZoneDirections: FocusZoneDirection[] = ['bidirectional', 'horizontal', 'vertical', 'none'];
@ -28,9 +29,17 @@ export const FocusZoneListWrapper: React.FunctionComponent<FocusZoneListWrapperP
const buttonProps: ButtonProps = { children: 'Click to Focus', style: focusZoneTestStyles.listWrapperButton };
return (
<>
<Button {...buttonProps} testID={beforeID} />
<Button
{...buttonProps}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(beforeID)}
/>
{children}
<Button {...buttonProps} testID={afterID} />
<Button
{...buttonProps}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(afterID)}
/>
</>
);
};
@ -53,10 +62,11 @@ export const GridOfButtons: React.FunctionComponent<GridOfButtonsProps> = (props
const gridIndex = heightIndex * props.gridWidth + widthIndex + 1;
return (
<GridButton
testID={props.e2etesting ? FOCUSZONE_GRID_BUTTON(gridIndex) : undefined}
key={widthIndex}
style={focusZoneTestStyles.focusZoneButton}
componentRef={gridIndex === props.tabbableIdx ? props.tabRef : undefined}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(props.e2etesting ? FOCUSZONE_GRID_BUTTON(gridIndex) : undefined)}
>
<Text>{gridIndex}</Text>
</GridButton>
@ -81,11 +91,14 @@ export const FocusZone2D: React.FunctionComponent = () => {
return (
<View style={commonTestStyles.root}>
<View style={commonTestStyles.settings}>
<Text variant="subheaderSemibold" testID={FOCUSZONE_TEST_COMPONENT}>
<Text
variant="subheaderSemibold"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOCUSZONE_TEST_COMPONENT)}
>
FocusZone Direction
</Text>
<MenuButton
testID={FOCUSZONE_DIRECTION_PICKER}
content={`Current direction: ${direction}`}
menuItems={FocusZoneDirections.map((dir) => ({
itemKey: dir,
@ -93,20 +106,36 @@ export const FocusZone2D: React.FunctionComponent = () => {
testID: FOCUSZONE_DIRECTION_ID(dir),
}))}
onItemClick={(dir) => setDirection(dir as FocusZoneDirection)}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOCUSZONE_DIRECTION_PICKER)}
/>
<Switch testID={FOCUSZONE_TWO_DIM_SWITCH} label="2D Navigation" checked={is2DNav} onChange={(_, checked) => set2dNav(checked)} />
<Switch testID={FOCUSZONE_DISABLED_SWITCH} label="Disabled" checked={isDisabled} onChange={(_, checked) => setDisabled(checked)} />
<Switch
testID={FOCUSZONE_CIRCLE_NAV_SWITCH}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOCUSZONE_TWO_DIM_SWITCH)}
label="2D Navigation"
checked={is2DNav}
onChange={(_, checked) => set2dNav(checked)}
/>
<Switch
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOCUSZONE_DISABLED_SWITCH)}
label="Disabled"
checked={isDisabled}
onChange={(_, checked) => setDisabled(checked)}
/>
<Switch
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOCUSZONE_CIRCLE_NAV_SWITCH)}
label="Circular Navigation"
checked={isCircularNav}
onChange={(_, checked) => setIsCircularNav(checked)}
/>
<Switch
testID={FOCUSZONE_DEFAULT_TABBABLE_SWITCH}
label="Use Default Tabbable Element"
checked={useDeffaultTabbableElement}
onChange={(_, checked) => setUseDeffaultTabbableElement(checked)}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOCUSZONE_DEFAULT_TABBABLE_SWITCH)}
/>
</View>

Просмотреть файл

@ -9,6 +9,7 @@ import {
LINK_NO_A11Y_LABEL_COMPONENT,
LINK_TEST_COMPONENT_LABEL,
} from '../../../../E2E/src/Link/consts';
import { testProps } from '../Common/TestProps';
export const LinkE2ETest: React.FunctionComponent = () => {
const doPress = (): void => {
@ -20,10 +21,17 @@ export const LinkE2ETest: React.FunctionComponent = () => {
<Link
url="https://www.bing.com/"
content="Link with Accessibility Label."
testID={LINK_TEST_COMPONENT}
accessibilityLabel={LINK_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(LINK_TEST_COMPONENT)}
/>
<Link
url="https://www.bing.com/"
onPress={doPress}
content={LINK_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(LINK_NO_A11Y_LABEL_COMPONENT)}
/>
<Link url="https://www.bing.com/" onPress={doPress} content={LINK_TEST_COMPONENT_LABEL} testID={LINK_NO_A11Y_LABEL_COMPONENT} />
</Stack>
);
};

Просмотреть файл

@ -9,6 +9,7 @@ import {
EXPERIMENTAL_LINK_NO_A11Y_LABEL_COMPONENT,
EXPERIMENTAL_LINK_TEST_COMPONENT_LABEL,
} from '../../../../E2E/src/LinkExperimental/consts';
import { testProps } from '../Common/TestProps';
export const LinkE2ETest: React.FunctionComponent = () => {
const doPress = (): void => {
@ -19,12 +20,17 @@ export const LinkE2ETest: React.FunctionComponent = () => {
<Stack style={stackStyle}>
<Link
url="https://www.bing.com/"
testID={EXPERIMENTAL_LINK_TEST_COMPONENT}
accessibilityLabel={EXPERIMENTAL_LINK_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_LINK_TEST_COMPONENT)}
>
Link with Accessibility Label
</Link>
<Link onPress={doPress} testID={EXPERIMENTAL_LINK_NO_A11Y_LABEL_COMPONENT}>
<Link
onPress={doPress}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_LINK_NO_A11Y_LABEL_COMPONENT)}
>
{EXPERIMENTAL_LINK_TEST_COMPONENT_LABEL}
</Link>
</Stack>

Просмотреть файл

@ -19,6 +19,7 @@ import {
MENUITEM_DISABLED_COMPONENT,
MENUITEM_CALLBACK_LABEL,
} from '../../../../E2E/src/Menu/consts';
import { testProps } from '../Common/TestProps';
export const E2EMenuTest: React.FunctionComponent = () => {
const [menuOpened, setMenuOpened] = React.useState(false);
@ -42,34 +43,76 @@ export const E2EMenuTest: React.FunctionComponent = () => {
return (
<Stack style={stackStyle}>
<View style={{ flexDirection: 'row' }}>
{menuOpened ? <Text testID={MENU_ON_OPEN}>Menu opened</Text> : <Text testID={MENU_ON_CLOSE}>Menu closed</Text>}
<Button onClick={onResetClick} testID={MENU_CALLBACK_RESET_BUTTON}>
{menuOpened ? (
<Text /* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */ {...testProps(MENU_ON_OPEN)}>
Menu opened
</Text>
) : (
<Text /* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */ {...testProps(MENU_ON_CLOSE)}>
Menu closed
</Text>
)}
<Button
onClick={onResetClick}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */ {...testProps(
MENU_CALLBACK_RESET_BUTTON,
)}
>
Reset Item Callback
</Button>
<Menu open={menuOpened} onOpenChange={onOpenChange}>
<MenuTrigger>
<Button testID={MENUTRIGGER_TEST_COMPONENT}>Test</Button>
<Button
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUTRIGGER_TEST_COMPONENT)}
>
Test
</Button>
</MenuTrigger>
<MenuPopover testID={MENUPOPOVER_TEST_COMPONENT}>
<MenuPopover
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUPOPOVER_TEST_COMPONENT)}
>
<MenuList>
<MenuItem
onClick={onItemClick}
testID={MENUITEM_TEST_COMPONENT}
accessibilityLabel={MENUITEM_ACCESSIBILITY_LABEL}
persistOnClick
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUITEM_TEST_COMPONENT)}
>
A plain MenuItem
</MenuItem>
<MenuItem onClick={onItemClick} testID={MENUITEM_DISABLED_COMPONENT} disabled persistOnClick>
<MenuItem
onClick={onItemClick}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUITEM_DISABLED_COMPONENT)}
disabled
persistOnClick
>
A second disabled plain MenuItem
</MenuItem>
<MenuItem testID={MENUITEM_NO_A11Y_LABEL_COMPONENT}>{MENUITEM_TEST_LABEL}</MenuItem>
<MenuItem testID={MENUITEM_FOURTH_COMPONENT}>A fourth plain MenuItem</MenuItem>
<MenuItem
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUITEM_NO_A11Y_LABEL_COMPONENT)}
>
{MENUITEM_TEST_LABEL}
</MenuItem>
<MenuItem
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUITEM_FOURTH_COMPONENT)}
>
A fourth plain MenuItem
</MenuItem>
</MenuList>
</MenuPopover>
</Menu>
</View>
<Text style={{ marginVertical: 4 }} testID={MENUITEM_CALLBACK_LABEL}>
<Text
style={{ marginVertical: 4 }}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENUITEM_CALLBACK_LABEL)}
>
{`onClick fired ${numOnClickCalls} times`}
</Text>
</Stack>

Просмотреть файл

@ -9,6 +9,7 @@ import {
MENU_BUTTON_NO_A11Y_LABEL_COMPONENT,
MENU_BUTTON_TEST_COMPONENT_LABEL,
} from '../../../../E2E/src/MenuButton/consts';
import { testProps } from '../Common/TestProps';
export const E2ETestMenuButton: React.FunctionComponent = () => {
const [lastMenuItemClicked, setLastMenuItemClicked] = React.useState(null);
@ -41,8 +42,9 @@ export const E2ETestMenuButton: React.FunctionComponent = () => {
menuItems={menuItems}
onItemClick={onItemClick}
contextualMenu={contextualMenuProps}
testID={MENU_BUTTON_TEST_COMPONENT}
accessibilityLabel={MENU_BUTTON_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENU_BUTTON_TEST_COMPONENT)}
/>
</View>
</View>
@ -53,7 +55,8 @@ export const E2ETestMenuButton: React.FunctionComponent = () => {
menuItems={menuItems}
onItemClick={onItemClick}
contextualMenu={contextualMenuProps}
testID={MENU_BUTTON_NO_A11Y_LABEL_COMPONENT}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(MENU_BUTTON_NO_A11Y_LABEL_COMPONENT)}
/>
</View>
</View>

Просмотреть файл

@ -10,6 +10,7 @@ import {
EXPERIMENTAL_MENU_BUTTON_NO_A11Y_LABEL_COMPONENT,
EXPERIMENTAL_MENU_BUTTON_TEST_COMPONENT_LABEL,
} from '../../../../E2E/src/MenuButtonExperimental/consts';
import { testProps } from '../Common/TestProps';
export const E2ETestExperimentalMenuButton: React.FunctionComponent = () => {
const [lastMenuItemClicked, setLastMenuItemClicked] = React.useState(null);
@ -42,8 +43,9 @@ export const E2ETestExperimentalMenuButton: React.FunctionComponent = () => {
menuItems={menuItems}
onItemClick={onItemClick}
contextualMenu={contextualMenuProps}
testID={EXPERIMENTAL_MENU_BUTTON_TEST_COMPONENT}
accessibilityLabel={EXPERIMENTAL_MENU_BUTTON_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_MENU_BUTTON_TEST_COMPONENT)}
/>
</View>
</View>
@ -54,7 +56,8 @@ export const E2ETestExperimentalMenuButton: React.FunctionComponent = () => {
menuItems={menuItems}
onItemClick={onItemClick}
contextualMenu={contextualMenuProps}
testID={EXPERIMENTAL_MENU_BUTTON_NO_A11Y_LABEL_COMPONENT}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_MENU_BUTTON_NO_A11Y_LABEL_COMPONENT)}
/>
</View>
</View>

Просмотреть файл

@ -15,6 +15,7 @@ import {
} from '../../../../E2E/src/RadioGroup/consts';
import { Stack } from '@fluentui-react-native/stack';
import { stackStyle } from '../Common/styles';
import { testProps } from '../Common/TestProps';
export const E2ERadioGroupTest: React.FunctionComponent = () => {
return (
@ -23,19 +24,41 @@ export const E2ERadioGroupTest: React.FunctionComponent = () => {
<RadioGroup
label="RadioGroup for E2E Testing - Ally Label Set"
accessibilityLabel={RADIOGROUP_ACCESSIBILITY_LABEL}
testID={RADIOGROUP_TEST_COMPONENT}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(RADIOGROUP_TEST_COMPONENT)}
>
<RadioButton
content="Option A"
buttonKey="A"
testID={FIRST_RADIO_BUTTON}
accessibilityLabel={FIRST_RADIO_BUTTON_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FIRST_RADIO_BUTTON)}
/>
<RadioButton
content={SECOND_RADIO_BUTTON_LABEL}
buttonKey="B"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SECOND_RADIO_BUTTON)}
/>
<RadioButton
content="Option C (disabled)"
buttonKey="C"
disabled={true}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(THIRD_RADIO_BUTTON)}
/>
<RadioButton
content="Option D"
buttonKey="C"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOURTH_RADIO_BUTTON)}
/>
<RadioButton content={SECOND_RADIO_BUTTON_LABEL} buttonKey="B" testID={SECOND_RADIO_BUTTON} />
<RadioButton content="Option C (disabled)" buttonKey="C" disabled={true} testID={THIRD_RADIO_BUTTON} />
<RadioButton content="Option D" buttonKey="C" testID={FOURTH_RADIO_BUTTON} />
</RadioGroup>
<RadioGroup label={RADIOGROUP_TEST_COMPONENT_LABEL} testID={RADIOGROUP_NO_A11Y_LABEL_COMPONENT}>
<RadioGroup
label={RADIOGROUP_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(RADIOGROUP_NO_A11Y_LABEL_COMPONENT)}
>
<RadioButton content="Option W" buttonKey="W" />
<RadioButton content="Option X" buttonKey="X" />
<RadioButton content="Option Y (disabled)" buttonKey="C" disabled={true} />

Просмотреть файл

@ -16,6 +16,7 @@ import {
} from '../../../../E2E/src/RadioGroupExperimental/consts';
import { Stack } from '@fluentui-react-native/stack';
import { stackStyle } from '../Common/styles';
import { testProps } from '../Common/TestProps';
export const E2ERadioGroupExperimentalTest: React.FunctionComponent = () => {
return (
@ -24,15 +25,48 @@ export const E2ERadioGroupExperimentalTest: React.FunctionComponent = () => {
<RadioGroup
label="RadioGroup for E2E Testing - Ally Label Set"
accessibilityLabel={EXPERIMENTAL_RADIOGROUP_ACCESSIBILITY_LABEL}
testID={EXPERIMENTAL_RADIOGROUP_TEST_COMPONENT}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_RADIOGROUP_TEST_COMPONENT)}
>
<Radio label="Option A" value="A" testID={FIRST_RADIO} accessibilityLabel={FIRST_RADIO_ACCESSIBILITY_LABEL} />
<Radio label={SECOND_RADIO_LABEL} value="B" testID={SECOND_RADIO} />
<Radio label="Option C (disabled)" value="C" disabled={true} testID={THIRD_RADIO} />
<Radio label="Option D" value="C" testID={FOURTH_RADIO} />
<Radio
label="Option A"
value="A"
accessibilityLabel={FIRST_RADIO_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FIRST_RADIO)}
/>
<Radio
label={SECOND_RADIO_LABEL}
value="B"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SECOND_RADIO)}
/>
<Radio
label="Option C (disabled)"
value="C"
disabled={true}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(THIRD_RADIO)}
/>
<Radio
label="Option D"
value="C"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FOURTH_RADIO)}
/>
</RadioGroup>
<RadioGroup label={EXPERIMENTAL_RADIOGROUP_TEST_COMPONENT_LABEL} testID={EXPERIMENTAL_RADIOGROUP_NO_A11Y_LABEL_COMPONENT}>
<Radio label="Option W" value="W" testID={FIFTH_RADIO} />
<RadioGroup
label={
EXPERIMENTAL_RADIOGROUP_TEST_COMPONENT_LABEL
} /* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_RADIOGROUP_NO_A11Y_LABEL_COMPONENT)}
>
<Radio
label="Option W"
value="W"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FIFTH_RADIO)}
/>
<Radio label="Option X" value="X" />
<Radio label="Option Y (disabled)" value="C" disabled={true} />
<Radio label="Option Z" value="Z" />

Просмотреть файл

@ -4,16 +4,18 @@ import { Stack } from '@fluentui-react-native/stack';
import { stackStyle } from '../Common/styles';
import { shimmerRectsAndRect } from './ShimmerTestElementSets';
import { SHIMMER_TEST_COMPONENT } from '../../../../E2E/src/Shimmer/consts';
import { testProps } from '../Common/TestProps';
export const E2ETestingShimmer: React.FunctionComponent<Record<string, never>> = () => {
return (
<Stack style={stackStyle}>
<Shimmer
testID={SHIMMER_TEST_COMPONENT}
elements={shimmerRectsAndRect()}
duration={2000}
delay={1000}
style={{ width: 300, height: 100 }}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SHIMMER_TEST_COMPONENT)}
/>
</Stack>
);

Просмотреть файл

@ -11,6 +11,7 @@ import {
SWITCH_ON_PRESS,
} from '../../../../E2E/src/Switch/consts';
import { Platform } from 'react-native';
import { testProps } from '../Common/TestProps';
export const E2ESwitchTest: React.FunctionComponent = () => {
const [switchPressed, setSwitchSwitchPressed] = React.useState(false);
@ -29,9 +30,26 @@ export const E2ESwitchTest: React.FunctionComponent = () => {
return (
<Stack style={memoizedStyles}>
<Switch testID={SWITCH_TEST_COMPONENT} label={'Switch Test'} onChange={onToggle} accessibilityLabel={SWITCH_ACCESSIBILITY_LABEL} />
{switchPressed ? <TextV1 testID={SWITCH_ON_PRESS}>Switch Toggled On</TextV1> : null}
<Switch label={SWITCH_TEST_COMPONENT_LABEL} testID={SWITCH_NO_A11Y_LABEL_COMPONENT} />
<Switch
label={'Switch Test'}
onChange={onToggle}
accessibilityLabel={SWITCH_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SWITCH_TEST_COMPONENT)}
/>
{switchPressed ? (
<TextV1
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SWITCH_ON_PRESS)}
>
Switch Toggled On
</TextV1>
) : null}
<Switch
label={SWITCH_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SWITCH_NO_A11Y_LABEL_COMPONENT)}
/>
</Stack>
);
};

Просмотреть файл

@ -16,25 +16,66 @@ import {
THIRD_TABS_ITEM_CONTENT,
FIRST_TABS_ITEM_CONTENT,
} from '../../../../E2E/src/Tabs/consts';
import { testProps } from '../Common/TestProps';
export const E2ETabsTest: React.FunctionComponent = () => {
return (
<View>
<View style={stackStyle}>
<Tabs label="Tabs" testID={TABS_TEST_COMPONENT} accessibilityLabel={TABS_ACCESSIBILITY_LABEL}>
<TabsItem headerText="Home" itemKey="A" testID={FIRST_TABS_ITEM} accessibilityLabel={FIRST_TABS_ITEM_ACCESSIBILITY_LABEL}>
<Text testID={FIRST_TABS_ITEM_CONTENT}>Tabs #1</Text>
<Tabs
label="Tabs"
accessibilityLabel={TABS_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(TABS_TEST_COMPONENT)}
>
<TabsItem
headerText="Home"
itemKey="A"
accessibilityLabel={FIRST_TABS_ITEM_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FIRST_TABS_ITEM)}
>
<Text
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(FIRST_TABS_ITEM_CONTENT)}
>
Tabs #1
</Text>
</TabsItem>
<TabsItem headerText="Files" itemKey="B" testID={SECOND_TABS_ITEM}>
<Text testID={SECOND_TABS_ITEM_CONTENT}>Tabs #2</Text>
<TabsItem
headerText="Files"
itemKey="B"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SECOND_TABS_ITEM)}
>
<Text
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(SECOND_TABS_ITEM_CONTENT)}
>
Tabs #2
</Text>
</TabsItem>
<TabsItem headerText={THIRD_TABS_ITEM_LABEL} itemKey="C" testID={THIRD_TABS_ITEM}>
<Text testID={THIRD_TABS_ITEM_CONTENT}>Tabs #3</Text>
<TabsItem
headerText={THIRD_TABS_ITEM_LABEL}
itemKey="C"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(THIRD_TABS_ITEM)}
>
<Text
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(THIRD_TABS_ITEM_CONTENT)}
>
Tabs #3
</Text>
</TabsItem>
</Tabs>
</View>
<View style={stackStyle}>
<Tabs label={TABS_TEST_COMPONENT_LABEL} testID={TABS_NO_A11Y_LABEL_COMPONENT}>
<Tabs
label={TABS_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(TABS_NO_A11Y_LABEL_COMPONENT)}
>
<TabsItem headerText="Home" itemKey="A">
<Text>Tabs #1</Text>
</TabsItem>

Просмотреть файл

@ -13,17 +13,24 @@ import {
EXPERIMENTAL_TABS_ITEM_NO_A11Y_LABEL_COMPONENT,
EXPERIMENTAL_TABS_ITEM_TEST_COMPONENT_LABEL,
} from '../../../../E2E/src/TabsExperimental/consts';
import { testProps } from '../Common/TestProps';
export const E2ETestExperimentalTabs: React.FunctionComponent = () => {
return (
<View>
<View style={stackStyle}>
<Tabs label="Tabs" testID={EXPERIMENTAL_TABS_TEST_COMPONENT} accessibilityLabel={EXPERIMENTAL_TABS_ACCESSIBILITY_LABEL}>
<Tabs
label="Tabs"
accessibilityLabel={EXPERIMENTAL_TABS_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_TABS_TEST_COMPONENT)}
>
<TabsItem
headerText="Home"
itemKey="A"
testID={EXPERIMENTAL_TABS_ITEM_TEST_COMPONENT}
accessibilityLabel={EXPERIMENTAL_TABS_ITEM_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_TABS_ITEM_TEST_COMPONENT)}
>
<Text>Tabs #1</Text>
</TabsItem>
@ -36,11 +43,16 @@ export const E2ETestExperimentalTabs: React.FunctionComponent = () => {
</Tabs>
</View>
<View style={stackStyle}>
<Tabs label={EXPERIMENTAL_TABS_TEST_COMPONENT_LABEL} testID={EXPERIMENTAL_TABS_NO_A11Y_LABEL_COMPONENT}>
<Tabs
label={EXPERIMENTAL_TABS_TEST_COMPONENT_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_TABS_NO_A11Y_LABEL_COMPONENT)}
>
<TabsItem
headerText={EXPERIMENTAL_TABS_ITEM_TEST_COMPONENT_LABEL}
itemKey="A"
testID={EXPERIMENTAL_TABS_ITEM_NO_A11Y_LABEL_COMPONENT}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_TABS_ITEM_NO_A11Y_LABEL_COMPONENT)}
>
<Text>Tabs #1</Text>
</TabsItem>

Просмотреть файл

@ -7,6 +7,7 @@ import { useTheme } from '@fluentui-react-native/theme-types';
import Svg, { G, Path, SvgProps } from 'react-native-svg';
import { SvgIconProps } from '@fluentui-react-native/icon';
import { Button } from '@fluentui-react-native/experimental-button';
import { testProps } from './Common/TestProps';
export type TestSection = {
name: string;
@ -119,7 +120,11 @@ export const Test = (props: TestProps): React.ReactElement<Record<string, never>
<Text style={styles.name} variant="heroSemibold">
{props.name}
</Text>
<Button testID="Focus_Button" style={styles.e2eFocusButton}>
<Button
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps('Focus_Button')}
style={styles.e2eFocusButton}
>
E2E Testing Button
</Button>
{props.spec && <Link url={props.spec} content="SPEC" />}
@ -172,7 +177,12 @@ export const Test = (props: TestProps): React.ReactElement<Record<string, never>
const TestComponent = section.component;
return (
<View key={index}>
<Text style={styles.section} variant="headerSemibold" testID={section.testID}>
<Text
style={styles.section}
variant="headerSemibold"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(section.testID)}
>
{section.name}
</Text>
<Separator />

Просмотреть файл

@ -3,15 +3,12 @@ import { View } from 'react-native';
import { Text } from '@fluentui/react-native';
import { Stack } from '@fluentui-react-native/stack';
import { stackStyle } from '../Common/styles';
import { TEXT_TESTPAGE } from '../../../../E2E/src/Text/consts';
export const StandardUsage: React.FunctionComponent = () => {
return (
<View>
<Stack style={stackStyle} gap={5}>
<Text variant="captionStandard" testID={TEXT_TESTPAGE}>
CaptionStandard
</Text>
<Text variant="captionStandard">CaptionStandard</Text>
<Text variant="secondaryStandard">SecondaryStandard</Text>
<Text variant="secondarySemibold">SecondarySemibold</Text>
<Text variant="bodyStandard">BodyStandard</Text>

Просмотреть файл

@ -13,27 +13,42 @@ import {
V1_TEXT_SECOND_COMPONENT,
V1_TEXT_SECOND_COMPONENT_CONTENT,
} from '../../../../E2E/src/Text/consts';
import { testProps } from '../Common/TestProps';
export const E2ETextTest: React.FunctionComponent = () => {
return (
<View>
<Stack style={stackStyle} gap={5}>
<Text variant="captionStandard" testID={V1_TEXT_FIRST_COMPONENT} accessibilityLabel={V1_TEXT_FIRST_ACCESSIBILITY_LABEL}>
<Text
variant="captionStandard"
accessibilityLabel={V1_TEXT_FIRST_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(V1_TEXT_FIRST_COMPONENT)}
>
Testing Text Component - Accessibility Label Set
</Text>
<Text variant="captionStandard" testID={V1_TEXT_SECOND_COMPONENT}>
<Text
variant="captionStandard"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(V1_TEXT_SECOND_COMPONENT)}
>
{V1_TEXT_SECOND_COMPONENT_CONTENT}
</Text>
</Stack>
<Stack style={stackStyle} gap={5}>
<DeprecatedText
variant="captionStandard"
testID={DEPRECATED_TEXT_FIRST_COMPONENT}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(DEPRECATED_TEXT_FIRST_COMPONENT)}
accessibilityLabel={DEPRECATED_TEXT_FIRST_ACCESSIBILITY_LABEL}
>
Testing Deprecated Text Component - Accessibility Label Set
</DeprecatedText>
<DeprecatedText variant="captionStandard" testID={DEPRECATED_TEXT_SECOND_COMPONENT}>
<DeprecatedText
variant="captionStandard"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(DEPRECATED_TEXT_SECOND_COMPONENT)}
>
{DEPRECATED_TEXT_SECOND_COMPONENT_CONTENT}
</DeprecatedText>
</Stack>

Просмотреть файл

@ -4,10 +4,12 @@ import { CustomizeUsage } from './CustomizeUsage';
import { PressableUsage } from './PressableUsage';
import { E2ETextTest } from './TextE2ETest';
import { Test, TestSection, PlatformStatus } from '../Test';
import { TEXT_TESTPAGE } from '../../../../E2E/src/index.consts';
const textSections: TestSection[] = [
{
name: 'Standard Usage',
testID: TEXT_TESTPAGE,
component: StandardUsage,
},
{

Просмотреть файл

@ -9,6 +9,7 @@ import {
EXPERIMENTAL_TEXT_NO_A11Y_LABEL_COMPONENT,
EXPERIMENTAL_TEXT_CONTENT,
} from '../../../../E2E/src/TextExperimental/consts';
import { testProps } from '../Common/TestProps';
export const E2EExperimentalTextTest: React.FunctionComponent = () => {
return (
@ -16,12 +17,17 @@ export const E2EExperimentalTextTest: React.FunctionComponent = () => {
<Stack style={stackStyle} gap={5}>
<Text
variant="captionStandard"
testID={EXPERIMENTAL_TEXT_TEST_COMPONENT}
accessibilityLabel={EXPERIMENTAL_TEXT_ACCESSIBILITY_LABEL}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_TEXT_TEST_COMPONENT)}
>
Testing Text Component - Accessibility Label Set
</Text>
<Text variant="captionStandard" testID={EXPERIMENTAL_TEXT_NO_A11Y_LABEL_COMPONENT}>
<Text
variant="captionStandard"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(EXPERIMENTAL_TEXT_NO_A11Y_LABEL_COMPONENT)}
>
{EXPERIMENTAL_TEXT_CONTENT}
</Text>
</Stack>

Просмотреть файл

@ -4,12 +4,17 @@ import { Text } from '@fluentui-react-native/experimental-text';
import { Stack } from '@fluentui-react-native/stack';
import { stackStyle } from '../Common/styles';
import { HOMEPAGE_EXPERIMENTAL_TEXT_BUTTON } from '../../../../E2E/src/TextExperimental/consts';
import { testProps } from '../Common/TestProps';
export const StandardUsage: React.FunctionComponent = () => {
return (
<View>
<Stack style={stackStyle} gap={5}>
<Text variant="captionStandard" testID={HOMEPAGE_EXPERIMENTAL_TEXT_BUTTON}>
<Text
variant="captionStandard"
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(HOMEPAGE_EXPERIMENTAL_TEXT_BUTTON)}
>
CaptionStandard
</Text>
<Text variant="secondaryStandard">SecondaryStandard</Text>

Просмотреть файл

@ -50,7 +50,7 @@ const Panel: React.FunctionComponent = () => {
<PrimaryButton onClick={onClick} content="Primary Button" disabled={disabled} />
<Button onClick={onClick} content="Default Button" disabled={disabled} />
<StealthButton onClick={onClick} content="Stealth Button" disabled={disabled} />
<Text testID={THEME_TESTPAGE}>This is a text element</Text>
<Text>This is a text element</Text>
<Button onClick={onClick} content="This button has longer text" disabled={disabled} />
</View>
);
@ -103,6 +103,7 @@ const SwatchList: React.FunctionComponent = () => {
const themeSections: TestSection[] = [
{
name: 'Component Examples',
testID: THEME_TESTPAGE,
component: Panel,
},
{

Просмотреть файл

@ -9,6 +9,7 @@ import { commonTestStyles } from '../Common/styles';
import { Text } from '@fluentui/react-native';
import { Test, TestSection, PlatformStatus } from '../Test';
import { TOKENS_TEST_COMPONENT, TOKEN_TESTPAGE } from '../../../../E2E/src/Tokens/consts';
import { testProps } from '../Common/TestProps';
const getThemedStyles = themedStyleSheet((theme: Theme) => {
return {
@ -49,7 +50,11 @@ const ColorToken: React.FunctionComponent<ColorTokenProps> = (p: ColorTokenProps
const themedStyles = getThemedStyles(useTheme());
return (
<View style={styles.swatchItem}>
<View style={[getSwatchColorStyle(p.name, p.color), themedStyles.swatch]} testID={TOKENS_TEST_COMPONENT} />
<View
style={[getSwatchColorStyle(p.name, p.color), themedStyles.swatch]}
/* For Android E2E testing purposes, testProps must be passed in after accessibilityLabel. */
{...testProps(TOKENS_TEST_COMPONENT)}
/>
<Text>{p.name}</Text>
</View>
);

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Basic E2E setup for android",
"packageName": "@fluentui-react-native/e2e-testing",
"email": "ayushsinghs@yahoo.in",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Basic E2E setup for android",
"packageName": "@fluentui-react-native/tester",
"email": "ayushsinghs@yahoo.in",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -62,7 +62,9 @@
"@fluentui-react-native/e2e-testing/appium-windows-driver",
"@fluentui-react-native/e2e-testing/appium-mac2-driver",
"@fluentui-react-native/e2e-testing/appium-xcuitest-driver",
"@fluentui-react-native/tester-win32/appium-windows-driver"
"@fluentui-react-native/tester-win32/appium-windows-driver",
"@fluentui-react-native/e2e-testing/appium-uiautomator2-driver",
"@fluentui-react-native/e2e-testing/appium-uiautomator2-server"
]
},
"resolutions": {

178
yarn.lock
Просмотреть файл

@ -76,7 +76,7 @@
json-schema "0.4.0"
source-map-support "0.5.21"
"@appium/support@^2.55.3", "@appium/support@^2.57.0", "@appium/support@^2.59.3", "@appium/support@^2.61.0", "@appium/support@^2.61.1":
"@appium/support@^2.55.3", "@appium/support@^2.57.0", "@appium/support@^2.59.3", "@appium/support@^2.60.0", "@appium/support@^2.61.0", "@appium/support@^2.61.1":
version "2.61.1"
resolved "https://registry.yarnpkg.com/@appium/support/-/support-2.61.1.tgz#d68b71ba8cf7b7e1940acedc52d2ced659232611"
integrity sha512-+KNWsyLaQ0sY2UfXLukFHv0fi7dJbkpWeF/j9rUNppwafStXX/pNQAEreexf2GJpleaeFOqUu2nYQ4T8jEZARA==
@ -4056,6 +4056,15 @@ acorn@^8.2.4, acorn@^8.8.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
adbkit-apkreader@^3.1.2:
version "3.2.0"
resolved "https://registry.yarnpkg.com/adbkit-apkreader/-/adbkit-apkreader-3.2.0.tgz#8d0bb1f733969e959992095ed7f2a8d658ec97a5"
integrity sha512-QwsxPYCqWSmCAiW/A4gq0eytb4jtZc7WNbECIhLCRfGEB38oXzIV/YkTpkOTQFKSg3S4Svb6y///qOUH7UrWWw==
dependencies:
bluebird "^3.4.7"
debug "~4.1.1"
yauzl "^2.7.0"
agent-base@6:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
@ -4208,6 +4217,70 @@ appdirsjs@^1.2.4:
resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.7.tgz#50b4b7948a26ba6090d4aede2ae2dc2b051be3b3"
integrity sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==
appium-adb@^9.10.14, appium-adb@^9.10.9:
version "9.10.16"
resolved "https://registry.yarnpkg.com/appium-adb/-/appium-adb-9.10.16.tgz#84d03da37d3fdb0e01b222d90f95553c63ab4c44"
integrity sha512-hJThF5aLE2R9n0NDf7YIECFJmt36tcdIuPPzAONRVMxkWZ+ZZS7Y3OLXugXMZEwA0ObsSk6sumQcfqXZ1aGmWw==
dependencies:
"@appium/support" "^2.60.0"
"@babel/runtime" "^7.0.0"
adbkit-apkreader "^3.1.2"
async-lock "^1.0.0"
asyncbox "^2.6.0"
bluebird "^3.4.7"
ini "^3.0.0"
lodash "^4.0.0"
lru-cache "^7.3.0"
semver "^7.0.0"
source-map-support "^0.x"
teen_process "^2.0.1"
utf7 "^1.0.2"
appium-android-driver@^5.7.0:
version "5.7.2"
resolved "https://registry.yarnpkg.com/appium-android-driver/-/appium-android-driver-5.7.2.tgz#0ecc5fc8096d69591eb8f04e8374ef6e8a5ad9cc"
integrity sha512-IeDJ5ANZG7k4szOASQTRGcWBWc53nkzZBgVQQ7HAcN+hy8ZrtZYIhwxAy995j46XzVHWwpCfwJ73wX1tN8t7LA==
dependencies:
"@babel/runtime" "^7.0.0"
appium-adb "^9.10.9"
appium-chromedriver "^5.2.0"
asyncbox "^2.8.0"
axios "^1.x"
bluebird "^3.4.7"
io.appium.settings "^4.2.1"
jimp "^0.x"
lodash "^4.17.4"
lru-cache "^7.3.0"
moment "^2.24.0"
moment-timezone "^0.5.26"
portfinder "^1.0.6"
portscanner "2.2.0"
semver "^7.0.0"
shared-preferences-builder "^0.x"
source-map-support "^0.x"
teen_process "^2.0.0"
ws "^8.0.0"
appium-chromedriver@^5.2.0, appium-chromedriver@^5.2.1:
version "5.2.7"
resolved "https://registry.yarnpkg.com/appium-chromedriver/-/appium-chromedriver-5.2.7.tgz#f80001e8f0703c345839dbe6609351e900ef1d26"
integrity sha512-84NCaq8+AjrXrFJ34U3gxU5jcrc7CWSzv9fTzS1fes05iFq3OWHMS0/0Tqr+cpMeV+JSlc0/u66P+BrmwxdNXg==
dependencies:
"@appium/base-driver" "^8.7.3"
"@appium/support" "^2.61.0"
"@babel/runtime" "^7.0.0"
"@xmldom/xmldom" "^0.x"
asyncbox "^2.0.2"
axios "^1.x"
bluebird "^3.5.1"
compare-versions "^5.0.0"
fancy-log "^2.0.0"
lodash "^4.17.4"
semver "^7.0.0"
source-map-support "^0.x"
teen_process "^2.0.0"
xpath "^0.x"
appium-idb@^1.0.0:
version "1.6.4"
resolved "https://registry.yarnpkg.com/appium-idb/-/appium-idb-1.6.4.tgz#6245ef36c2c4e2664a71fd3918f4f068984a058e"
@ -4287,6 +4360,30 @@ appium-remote-debugger@^9.1.1:
source-map-support "^0.x"
teen_process "^2.0.0"
appium-uiautomator2-driver@^2.10.2:
version "2.10.2"
resolved "https://registry.yarnpkg.com/appium-uiautomator2-driver/-/appium-uiautomator2-driver-2.10.2.tgz#7d9ed3143b54c2933acd4b45aa1de72e6bf87af6"
integrity sha512-W2kRQGfpVBriDrooBibXG0aMT5XDt1LAQTCiFkIlwum2N228G7Fx7ZElBZ4dE7b3WIfj7CMlHkTBvMwO4ONpog==
dependencies:
"@babel/runtime" "^7.0.0"
appium-adb "^9.10.14"
appium-android-driver "^5.7.0"
appium-chromedriver "^5.2.1"
appium-uiautomator2-server "^5.7.2"
asyncbox "^2.3.1"
axios "^1.x"
bluebird "^3.5.1"
css-selector-parser "^1.4.1"
lodash "^4.17.4"
portscanner "^2.2.0"
source-map-support "^0.x"
teen_process "^2.0.0"
appium-uiautomator2-server@^5.7.2:
version "5.7.4"
resolved "https://registry.yarnpkg.com/appium-uiautomator2-server/-/appium-uiautomator2-server-5.7.4.tgz#5019f7e641b76a2495695832e8008022229a94ae"
integrity sha512-0j8U+q0ik1ospK/lRovlPvOTPLfmaW67eh8YhMv7SC+Xo7wZCjsq3oiOxZkGz1LRwIwUhi452qbBKlT1m6MjFw==
appium-webdriveragent@^4.8.4:
version "4.10.10"
resolved "https://registry.yarnpkg.com/appium-webdriveragent/-/appium-webdriveragent-4.10.10.tgz#b34e45d9bd5cbbb3f2c03b187609e716fe621108"
@ -4777,7 +4874,7 @@ async-settle@^2.0.0:
dependencies:
async-done "^2.0.0"
async@^2.4.0, async@^2.6.0:
async@^2.4.0, async@^2.6.0, async@^2.6.4:
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
@ -4800,7 +4897,7 @@ asyncbox@2.9.2:
lodash "^4.17.4"
source-map-support "^0.5.5"
asyncbox@^2.0.2, asyncbox@^2.3.0, asyncbox@^2.3.1, asyncbox@^2.5.2, asyncbox@^2.5.3, asyncbox@^2.6.0, asyncbox@^2.9.2:
asyncbox@^2.0.2, asyncbox@^2.3.0, asyncbox@^2.3.1, asyncbox@^2.5.2, asyncbox@^2.5.3, asyncbox@^2.6.0, asyncbox@^2.8.0, asyncbox@^2.9.2:
version "2.9.4"
resolved "https://registry.yarnpkg.com/asyncbox/-/asyncbox-2.9.4.tgz#22a7cb9b7203a0183129243c0b1ead395d61f4d9"
integrity sha512-TCuA73K6Gvn+5tFGsWf4jc+PsR9RmYXw/AF0mv+CRB3VhHLjqHh/w9gPvYILnV0RcRFfjADHtzZexpxWlsP3Tg==
@ -5866,6 +5963,11 @@ commondir@^1.0.1:
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
compare-versions@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.1.tgz#14c6008436d994c3787aba38d4087fabe858555e"
integrity sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==
component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
@ -6176,13 +6278,20 @@ debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.2, de
dependencies:
ms "2.1.2"
debug@^3.1.0, debug@^3.2.6:
debug@^3.1.0, debug@^3.2.6, debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
debug@~4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@ -8398,6 +8507,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, i
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.1.tgz#c76ec81007875bc44d544ff7a11a55d12294102d"
integrity sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==
inquirer@8.2.4:
version "8.2.4"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4"
@ -8445,6 +8559,11 @@ invert-kv@^3.0.0:
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523"
integrity sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==
io.appium.settings@^4.2.1:
version "4.2.3"
resolved "https://registry.yarnpkg.com/io.appium.settings/-/io.appium.settings-4.2.3.tgz#224491f40e91176acc2fec0e67e8b3bda7bd2503"
integrity sha512-xKD/Vun4rx21h5IzugcboMuUQvBDFp0SuqsXCbcCy1WXnmkn00u85Qxk7MdfXAS4YyFbfZG21KDOqnFjivJPzQ==
ip@^1.1.5:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48"
@ -9523,7 +9642,7 @@ jetifier@^1.6.2:
resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.8.tgz#e88068697875cbda98c32472902c4d3756247798"
integrity sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==
jimp@0.16.2:
jimp@0.16.2, jimp@^0.x:
version "0.16.2"
resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.16.2.tgz#c03e296381ae37586e27f209d134d4596d112f7b"
integrity sha512-UpItBk81a92f8oEyoGYbO3YK4QcM0hoIyuGHmShoF9Ov63P5Qo7Q/X2xsAgnODmSuDJFOtrPtJd5GSWW4LKdOQ==
@ -10288,7 +10407,7 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lru-cache@^7.0.1:
lru-cache@^7.0.1, lru-cache@^7.3.0:
version "7.14.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.14.1.tgz#8da8d2f5f59827edb388e63e459ac23d6d408fea"
integrity sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==
@ -10862,7 +10981,7 @@ mkdirp-classic@^0.5.2:
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mkdirp@^0.5.1, mkdirp@~0.5.1:
mkdirp@^0.5.1, mkdirp@^0.5.6, mkdirp@~0.5.1:
version "0.5.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
@ -10874,7 +10993,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment-timezone@^0.x:
moment-timezone@^0.5.26, moment-timezone@^0.x:
version "0.5.39"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.39.tgz#342625a3b98810f04c8f4ea917e448d3525e600b"
integrity sha512-hoB6suq4ISDj7BDgctiOy6zljBsdYT0++0ZzZm9rtxIvJhIbQ3nmbgSWe7dNFGurl6/7b1OUkHlmN9JWgXVz7w==
@ -11899,7 +12018,16 @@ pngjs@^5.0.0:
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==
portscanner@2.2.0:
portfinder@^1.0.6:
version "1.0.32"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81"
integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==
dependencies:
async "^2.6.4"
debug "^3.2.7"
mkdirp "^0.5.6"
portscanner@2.2.0, portscanner@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.2.0.tgz#6059189b3efa0965c9d96a56b958eb9508411cf1"
integrity sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==
@ -13006,6 +13134,11 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
integrity sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
@ -13085,6 +13218,14 @@ shallow-clone@^3.0.0:
dependencies:
kind-of "^6.0.2"
shared-preferences-builder@^0.x:
version "0.0.4"
resolved "https://registry.yarnpkg.com/shared-preferences-builder/-/shared-preferences-builder-0.0.4.tgz#842316ed07704f921dc19dad0aaf0c9f5c37eb9c"
integrity sha512-6yy1O1zVAY8HWVjsaJzFzkmvmktlSvqnjsYZpWJ0dUrFS5Rfn1a8P7h+7zyl9MTqUfSXeaE7De6Yymx3OszxlQ==
dependencies:
lodash "^4.17.4"
xmlbuilder "^9.0.1"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@ -14206,6 +14347,13 @@ username@^5.1.0:
execa "^1.0.0"
mem "^4.3.0"
utf7@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/utf7/-/utf7-1.0.2.tgz#955f490aae653ba220b9456a0a8776c199360991"
integrity sha512-qQrPtYLLLl12NF4DrM9CvfkxkYI97xOb5dsnGZHE3teFr0tWiEZ9UdgMPczv24vl708cYMpe6mGXGHrotIp3Bw==
dependencies:
semver "~5.3.0"
utf8-byte-length@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
@ -14701,6 +14849,11 @@ xmlbuilder@^15.1.1:
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5"
integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==
xmlbuilder@^9.0.1:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
integrity sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==
xmlbuilder@~11.0.0:
version "11.0.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
@ -14733,6 +14886,11 @@ xpath@^0.0.27:
resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92"
integrity sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==
xpath@^0.x:
version "0.0.32"
resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.32.tgz#1b73d3351af736e17ec078d6da4b8175405c48af"
integrity sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@ -14843,7 +15001,7 @@ yarn-install@^1.0.0:
chalk "^1.1.3"
cross-spawn "^4.0.2"
yauzl@2.10.0, yauzl@^2.10.0:
yauzl@2.10.0, yauzl@^2.10.0, yauzl@^2.7.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==