Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* @format
*/

import {app} from '@react-native-windows/automation';
import {dumpVisualTree} from '@react-native-windows/automation-commands';
import {goToComponentExample} from './RNTesterNavigation';
import {verifyNoErrorLogs} from './Helpers';

beforeAll(async () => {
// If window is partially offscreen, tests will fail to click on certain elements
await app.setWindowPosition(0, 0);
await app.setWindowSize(1000, 1250);
await goToComponentExample('LegacyControlStyleTest');
});

afterEach(async () => {
await verifyNoErrorLogs();
});

describe('LegacyControlStyleTest', () => {
/* Test case #1: Controls style with regular border */
test('ControlStyleTestWithRegularBorder', async () => {
const dump = await dumpVisualTree('control-style-switch-view');
expect(dump).toMatchSnapshot();
});

/* Test case #2: Click button once, update controls style and round border*/
test('ControlStyleTestWithRoundBorder', async () => {
await toggleControlBorder();
const dump = await dumpVisualTree('control-style-switch-view');
expect(dump).toMatchSnapshot();
});

/* Test case #3: Click button one more, return to #1*/
test('ControlStyleTestWithRegularBorder #2', async () => {
await toggleControlBorder();
const dump = await dumpVisualTree('control-style-switch-view');
expect(dump).toMatchSnapshot();
});
});

async function toggleControlBorder() {
const showBorderToggle = await app.findElementByTestID('show-border-toggle');
await showBorderToggle.click();
}
62 changes: 62 additions & 0 deletions packages/e2e-test-app-fabric/test/LegacyImageTest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* @format
*/

import {app} from '@react-native-windows/automation';
import {dumpVisualTree} from '@react-native-windows/automation-commands';
import {goToComponentExample} from './RNTesterNavigation';
import {verifyNoErrorLogs} from './Helpers';

beforeAll(async () => {
// If window is partially offscreen, tests will fail to click on certain elements
await app.setWindowPosition(0, 0);
await app.setWindowSize(1000, 1250);
await goToComponentExample('LegacyImageTest');
});

afterEach(async () => {
await verifyNoErrorLogs();
});

describe('LegacyImageTest', () => {
/* Test case #1: view and image displayed with no border and cornerRadius */
test('ImageWithoutBorderTest', async () => {
const dump = await dumpVisualTree('image-container');
expect(dump).toMatchSnapshot();
});

/* Test case #2: Click button once, update view and image with round border*/
test('ImageWithBorderTest', async () => {
await toggleImageBorder();
const dump = await dumpVisualTree('image-container');
expect(dump).toMatchSnapshot();
});

/* Test case #3: Click button one more, remove border from view and image but tree structure is different from #1*/
test('ImageWithoutBorderTestOneMoreClick', async () => {
await toggleImageBorder();
const dump = await dumpVisualTree('image-container');
expect(dump).toMatchSnapshot();
});

test('ImageRTLTest', async () => {
await toggleRTLMode();
const dump = await dumpVisualTree('image-container');
expect(dump).toMatchSnapshot();
});
});

async function toggleImageBorder() {
const imageBorderToggle = await app.findElementByTestID(
'toggle-border-button',
);
await imageBorderToggle.click();
}

async function toggleRTLMode() {
const rtlToggleButton = await app.findElementByTestID('set-rtl-button');
await rtlToggleButton.click();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* @format
*/

import {app} from '@react-native-windows/automation';
import {dumpVisualTree} from '@react-native-windows/automation-commands';
import {goToComponentExample} from './RNTesterNavigation';
import {verifyNoErrorLogs} from './Helpers';

beforeAll(async () => {
// If window is partially offscreen, tests will fail to click on certain elements
await app.setWindowPosition(0, 0);
await app.setWindowSize(1000, 1250);
await goToComponentExample('LegacySelectableTextTest');
});

afterEach(async () => {
await verifyNoErrorLogs();
});

describe('LegacySelectableTextTest', () => {
beforeEach(async () => {
await clearState();
});

test('PressableWhenNotSelectable', async () => {
const textExample = await app.findElementByTestID('text-example');
await textExample.click();
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('DoubleClickWhenNotSelectable', async () => {
const textExample = await app.findElementByTestID('text-example');
await textExample.doubleClick();
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('PressableWhenSelectable', async () => {
await toggleSelectable();
const textExample = await app.findElementByTestID('text-example');
await textExample.click();
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('DoubleClickWhenSelectable', async () => {
await toggleSelectable();
const textExample = await app.findElementByTestID('text-example');
await textExample.doubleClick();
const dump = await dumpVisualTree('pressed-state');
if (dump.Text === 'Pressed: 2 times.') {
// Due to the hardcoded speed between clicks in WinAppDriver, this test
// can be flaky on Windows Server 2022. Detect and warn here rather than
// disabling the entire test.
console.warn('DoubleClickWhenSelectable registered two clicks.');
dump.Text = 'Pressed: 1 times.';
}
expect(dump).toMatchSnapshot();
});
});

async function clearState() {
const clearButton = await app.findElementByTestID('clear-state-button');
await clearButton.click();
}

async function toggleSelectable() {
const toggleButton = await app.findElementByTestID(
'toggle-selectable-button',
);
await toggleButton.click();
}
147 changes: 147 additions & 0 deletions packages/e2e-test-app-fabric/test/LegacyTextHitTestTest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/**
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* @format
*/

import {app} from '@react-native-windows/automation';
import {dumpVisualTree} from '@react-native-windows/automation-commands';
import {goToComponentExample} from './RNTesterNavigation';
import {verifyNoErrorLogs} from './Helpers';

beforeAll(async () => {
// If window is partially offscreen, tests will fail to click on certain elements
await app.setWindowPosition(0, 0);
await app.setWindowSize(1000, 1250);
await goToComponentExample('LegacyTextHitTestTest');
});

afterEach(async () => {
await verifyNoErrorLogs();
});

describe('LegacyTextHitTestTest', () => {
beforeEach(async () => {
await clearState();
});

test('VirtualTextPressable', async () => {
await clickAt('virtual-text', {pctX: 0.85});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('TextPressableWithVirtualText', async () => {
await clickAt('nested-text', {pctX: 0.9});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('MultilineTextPressable', async () => {
await clickAt('multiline-text', {pctX: 0.15, pctY: 0.75});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('MultilineRTLTextPressable', async () => {
await clickAt('multiline-rtl-text', {pctX: 0.85, pctY: 0.25});
await clickAt('multiline-rtl-text', {pctX: 0.1, pctY: 0.75});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('RTLTextPressable', async () => {
await clickAt('rtl-text', {pctX: 0.85});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('RTLTextInRTLFlowPressable', async () => {
await clickAt('rtl-rtl-flow-text', {pctX: 0.8});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('LTRTextInRTLFlowPressable', async () => {
await clickAt('ltr-rtl-flow-text', {pctX: 0.9});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('BidirectionalTextPressable', async () => {
await clickAt('bidirectional-text', {pctX: 0.8});
await clickAt('bidirectional-text', {pctX: 0.95});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('BidirectionalTextSeparateRunsPressable', async () => {
await clickAt('separate-bidirectional-text', {pctX: 0.8});
await clickAt('separate-bidirectional-text', {pctX: 0.95});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('BidirectionalTextSeparateRunsEdgeCasePressable', async () => {
await clickAt('separate-bidirectional-text', {pctX: 0.62});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('InsertedVirtualTextPressable', async () => {
await clickAt('inserted-text', {pctX: 0.85});
await clickAt('inserted-text', {pctX: 0.9});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('ToggleVirtualTextPressable', async () => {
await clickAt('toggled-text', {pctX: 0.9});
await clickAt('toggled-text', {pctX: 0.9});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('WrappedLTRInRTLFlowEdgeCaseNotPressable', async () => {
await clickAt('wrapped-ltr-rtl-flow-text', {pctX: 0.85, pctY: 0.25});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('MultilineRTLTextEdgeCaseNotPressable', async () => {
await clickAt('multiline-rtl-text', {pctX: 0.765, pctY: 0.25});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});

test('BidirectionalTextPressableEdgeCaseNotPressable', async () => {
await clickAt('bidirectional-text', {pctX: 0.61});
const dump = await dumpVisualTree('pressed-state');
expect(dump).toMatchSnapshot();
});
});

async function clearState() {
const clearButton = await app.findElementByTestID('clear-state-button');
await clearButton.click();
}

async function clickAt(
name: string,
{pctX, pctY = 0.5}: {pctX: number; pctY?: number},
) {
const target = await app.findElementByTestID(name);
const {width, height} = await target.getSize();

// The webdriverio package computes the offsets from the center point of the
// target. Additionally, the package uses raw pixels. To make this test more
// robust to different screen resolutions and scale settings, the test cases
// are declared using relatively percentages for where in the hit target to
// click, and subtracts the center point so the declared offsets are absolute
// relative to the origin of the target (i.e., top-left corner).
await target.click({
x: Math.round(pctX * width - width / 2),
y: Math.round(pctY * height - height / 2),
});
}
Loading