@fluentui-react-native/tester 0.101.6 → 0.101.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +193 -1
- package/CHANGELOG.md +45 -2
- package/lib/E2E/FocusZone/pages/FocusZonePageObject.d.ts +37 -0
- package/lib/E2E/FocusZone/pages/FocusZonePageObject.d.ts.map +1 -1
- package/lib/E2E/FocusZone/pages/FocusZonePageObject.js +197 -4
- package/lib/E2E/FocusZone/pages/FocusZonePageObject.js.map +1 -1
- package/lib/E2E/FocusZone/specs/FocusZone.spec.win.js +457 -0
- package/lib/E2E/FocusZone/specs/FocusZone.spec.win.js.map +1 -1
- package/lib/E2E/common/BasePage.d.ts +2 -0
- package/lib/E2E/common/BasePage.d.ts.map +1 -1
- package/lib/E2E/common/BasePage.js +34 -14
- package/lib/E2E/common/BasePage.js.map +1 -1
- package/lib/E2E/common/consts.d.ts +15 -0
- package/lib/E2E/common/consts.d.ts.map +1 -1
- package/lib/TestComponents/Common/MenuPicker.d.ts +2 -0
- package/lib/TestComponents/Common/MenuPicker.d.ts.map +1 -1
- package/lib/TestComponents/Common/MenuPicker.js +2 -2
- package/lib/TestComponents/Common/MenuPicker.js.map +1 -1
- package/lib/TestComponents/FocusZone/FocusZoneE2ETest.d.ts +20 -0
- package/lib/TestComponents/FocusZone/FocusZoneE2ETest.d.ts.map +1 -0
- package/lib/TestComponents/FocusZone/FocusZoneE2ETest.js +51 -0
- package/lib/TestComponents/FocusZone/FocusZoneE2ETest.js.map +1 -0
- package/lib/TestComponents/FocusZone/FocusZoneTest.d.ts.map +1 -1
- package/lib/TestComponents/FocusZone/FocusZoneTest.js +26 -70
- package/lib/TestComponents/FocusZone/FocusZoneTest.js.map +1 -1
- package/lib/TestComponents/FocusZone/consts.d.ts +10 -0
- package/lib/TestComponents/FocusZone/consts.d.ts.map +1 -1
- package/lib/TestComponents/FocusZone/consts.js +11 -0
- package/lib/TestComponents/FocusZone/consts.js.map +1 -1
- package/lib/TestComponents/FocusZone/styles.d.ts +5 -0
- package/lib/TestComponents/FocusZone/styles.d.ts.map +1 -1
- package/lib/TestComponents/FocusZone/styles.js +5 -0
- package/lib/TestComponents/FocusZone/styles.js.map +1 -1
- package/lib-commonjs/E2E/FocusZone/pages/FocusZonePageObject.d.ts +37 -0
- package/lib-commonjs/E2E/FocusZone/pages/FocusZonePageObject.d.ts.map +1 -1
- package/lib-commonjs/E2E/FocusZone/pages/FocusZonePageObject.js +196 -3
- package/lib-commonjs/E2E/FocusZone/pages/FocusZonePageObject.js.map +1 -1
- package/lib-commonjs/E2E/FocusZone/specs/FocusZone.spec.win.js +457 -0
- package/lib-commonjs/E2E/FocusZone/specs/FocusZone.spec.win.js.map +1 -1
- package/lib-commonjs/E2E/common/BasePage.d.ts +2 -0
- package/lib-commonjs/E2E/common/BasePage.d.ts.map +1 -1
- package/lib-commonjs/E2E/common/BasePage.js +34 -14
- package/lib-commonjs/E2E/common/BasePage.js.map +1 -1
- package/lib-commonjs/E2E/common/consts.d.ts +15 -0
- package/lib-commonjs/E2E/common/consts.d.ts.map +1 -1
- package/lib-commonjs/TestComponents/Common/MenuPicker.d.ts +2 -0
- package/lib-commonjs/TestComponents/Common/MenuPicker.d.ts.map +1 -1
- package/lib-commonjs/TestComponents/Common/MenuPicker.js +2 -2
- package/lib-commonjs/TestComponents/Common/MenuPicker.js.map +1 -1
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneE2ETest.d.ts +20 -0
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneE2ETest.d.ts.map +1 -0
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneE2ETest.js +57 -0
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneE2ETest.js.map +1 -0
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneTest.d.ts.map +1 -1
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneTest.js +27 -71
- package/lib-commonjs/TestComponents/FocusZone/FocusZoneTest.js.map +1 -1
- package/lib-commonjs/TestComponents/FocusZone/consts.d.ts +10 -0
- package/lib-commonjs/TestComponents/FocusZone/consts.d.ts.map +1 -1
- package/lib-commonjs/TestComponents/FocusZone/consts.js +14 -1
- package/lib-commonjs/TestComponents/FocusZone/consts.js.map +1 -1
- package/lib-commonjs/TestComponents/FocusZone/styles.d.ts +5 -0
- package/lib-commonjs/TestComponents/FocusZone/styles.d.ts.map +1 -1
- package/lib-commonjs/TestComponents/FocusZone/styles.js +5 -0
- package/lib-commonjs/TestComponents/FocusZone/styles.js.map +1 -1
- package/package.json +29 -29
- package/src/E2E/FocusZone/pages/FocusZonePageObject.ts +135 -4
- package/src/E2E/FocusZone/specs/FocusZone.spec.win.ts +177 -2
- package/src/E2E/common/BasePage.ts +8 -3
- package/src/E2E/common/consts.ts +17 -0
- package/src/TestComponents/Common/MenuPicker.tsx +5 -2
- package/src/TestComponents/FocusZone/FocusZoneE2ETest.tsx +126 -0
- package/src/TestComponents/FocusZone/FocusZoneTest.tsx +40 -127
- package/src/TestComponents/FocusZone/consts.ts +17 -0
- package/src/TestComponents/FocusZone/styles.ts +5 -0
|
@@ -1,12 +1,115 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FocusZoneDirection } from '@fluentui/react-native';
|
|
2
|
+
import { Attribute, AttributeValue, Keys } from '../../common/consts';
|
|
3
|
+
import {
|
|
4
|
+
FOCUSZONE_CIRCLE_NAV_SWITCH,
|
|
5
|
+
FOCUSZONE_DEFAULT_TABBABLE_SWITCH,
|
|
6
|
+
FOCUSZONE_DIRECTION_ID,
|
|
7
|
+
FOCUSZONE_DIRECTION_PICKER,
|
|
8
|
+
FOCUSZONE_DISABLED_SWITCH,
|
|
9
|
+
FOCUSZONE_GRID_AFTER,
|
|
10
|
+
FOCUSZONE_GRID_BEFORE,
|
|
11
|
+
FOCUSZONE_GRID_BUTTON,
|
|
12
|
+
FOCUSZONE_TESTPAGE,
|
|
13
|
+
FOCUSZONE_TEST_COMPONENT,
|
|
14
|
+
FOCUSZONE_TWO_DIM_SWITCH,
|
|
15
|
+
HOMEPAGE_FOCUSZONE_BUTTON,
|
|
16
|
+
} from '../../../TestComponents/FocusZone/consts';
|
|
2
17
|
import { BasePage, By } from '../../common/BasePage';
|
|
3
18
|
|
|
19
|
+
export const enum GridFocusZoneOption {
|
|
20
|
+
SetDirection = 0,
|
|
21
|
+
Set2DNavigation,
|
|
22
|
+
SetCircularNavigation,
|
|
23
|
+
UseDefaultTabbableElement,
|
|
24
|
+
Disable,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const enum GridButtonSelector {
|
|
28
|
+
Before = 0,
|
|
29
|
+
One,
|
|
30
|
+
Two,
|
|
31
|
+
Three,
|
|
32
|
+
Four,
|
|
33
|
+
Five,
|
|
34
|
+
Six,
|
|
35
|
+
Seven,
|
|
36
|
+
Eight,
|
|
37
|
+
Nine,
|
|
38
|
+
After,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type BooleanGridFocusZoneOption =
|
|
42
|
+
| GridFocusZoneOption.UseDefaultTabbableElement
|
|
43
|
+
| GridFocusZoneOption.Set2DNavigation
|
|
44
|
+
| GridFocusZoneOption.SetCircularNavigation
|
|
45
|
+
| GridFocusZoneOption.Disable;
|
|
46
|
+
|
|
4
47
|
class FocusZonePageObject extends BasePage {
|
|
5
|
-
// OVERRIDE: We use isExisting() here instead of isDisplayed() because FocusZone does not have any UI to it, it's simply
|
|
6
|
-
// a wrapper that adds keyboard focus functionality
|
|
7
48
|
async waitForPrimaryElementDisplayed(timeout?: number): Promise<void> {
|
|
8
49
|
const errorMsg = 'The FocusZone UI Element did not load correctly. Please see logs.';
|
|
9
|
-
await this.waitForCondition(async () => await this._primaryComponent.
|
|
50
|
+
await this.waitForCondition(async () => await this._primaryComponent.isDisplayed(), errorMsg, timeout);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async resetTest() {
|
|
54
|
+
await this.configureGridFocusZone(GridFocusZoneOption.SetDirection, 'bidirectional');
|
|
55
|
+
await this.configureGridFocusZone(GridFocusZoneOption.Set2DNavigation, false);
|
|
56
|
+
await this.configureGridFocusZone(GridFocusZoneOption.SetCircularNavigation, false);
|
|
57
|
+
await this.configureGridFocusZone(GridFocusZoneOption.Disable, false);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async configureGridFocusZone(option: GridFocusZoneOption.SetDirection, direction: FocusZoneDirection);
|
|
61
|
+
async configureGridFocusZone(option: BooleanGridFocusZoneOption, value: boolean);
|
|
62
|
+
async configureGridFocusZone(option: GridFocusZoneOption, arg: any): Promise<void> {
|
|
63
|
+
let switchElement: WebdriverIO.Element;
|
|
64
|
+
switch (option) {
|
|
65
|
+
case GridFocusZoneOption.SetDirection:
|
|
66
|
+
await (await this._directionPicker).click();
|
|
67
|
+
await browser.waitUntil(async () => await (await this._getGridFocusZoneMenuOption(arg)).isDisplayed());
|
|
68
|
+
await (await this._getGridFocusZoneMenuOption(arg)).click();
|
|
69
|
+
return;
|
|
70
|
+
case GridFocusZoneOption.Set2DNavigation:
|
|
71
|
+
switchElement = await this._twoDimSwitch;
|
|
72
|
+
break;
|
|
73
|
+
case GridFocusZoneOption.SetCircularNavigation:
|
|
74
|
+
switchElement = await this._circleNavSwitch;
|
|
75
|
+
break;
|
|
76
|
+
case GridFocusZoneOption.UseDefaultTabbableElement:
|
|
77
|
+
switchElement = await this._defaultTabbableElementSwitch;
|
|
78
|
+
break;
|
|
79
|
+
case GridFocusZoneOption.Disable:
|
|
80
|
+
switchElement = await this._disabledSwitch;
|
|
81
|
+
break;
|
|
82
|
+
default:
|
|
83
|
+
}
|
|
84
|
+
const switchValue = await switchElement.isSelected();
|
|
85
|
+
if (switchValue !== arg) {
|
|
86
|
+
await switchElement.click();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async sendKeys(selector: GridButtonSelector, keys: Keys[]): Promise<void> {
|
|
91
|
+
const btn = await this._getGridButton(selector);
|
|
92
|
+
await btn.addValue(keys);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async gridButtonIsFocused(selector: GridButtonSelector): Promise<boolean> {
|
|
96
|
+
const btn = await this._getGridButton(selector);
|
|
97
|
+
return (await this.getElementAttribute(btn, Attribute.IsFocused)) === AttributeValue.true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private async _getGridButton(selector: GridButtonSelector): Promise<WebdriverIO.Element> {
|
|
101
|
+
switch (selector) {
|
|
102
|
+
case GridButtonSelector.Before:
|
|
103
|
+
return await this._gridBeforeButton;
|
|
104
|
+
case GridButtonSelector.After:
|
|
105
|
+
return await this._gridAfterButton;
|
|
106
|
+
default:
|
|
107
|
+
return await By(FOCUSZONE_GRID_BUTTON(selector));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private async _getGridFocusZoneMenuOption(direction: FocusZoneDirection) {
|
|
112
|
+
return await By(FOCUSZONE_DIRECTION_ID(direction));
|
|
10
113
|
}
|
|
11
114
|
|
|
12
115
|
/*****************************************/
|
|
@@ -27,6 +130,34 @@ class FocusZonePageObject extends BasePage {
|
|
|
27
130
|
get _pageButton() {
|
|
28
131
|
return By(HOMEPAGE_FOCUSZONE_BUTTON);
|
|
29
132
|
}
|
|
133
|
+
|
|
134
|
+
get _directionPicker() {
|
|
135
|
+
return By(FOCUSZONE_DIRECTION_PICKER);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
get _twoDimSwitch() {
|
|
139
|
+
return By(FOCUSZONE_TWO_DIM_SWITCH);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get _disabledSwitch() {
|
|
143
|
+
return By(FOCUSZONE_DISABLED_SWITCH);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get _circleNavSwitch() {
|
|
147
|
+
return By(FOCUSZONE_CIRCLE_NAV_SWITCH);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
get _defaultTabbableElementSwitch() {
|
|
151
|
+
return By(FOCUSZONE_DEFAULT_TABBABLE_SWITCH);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
get _gridBeforeButton() {
|
|
155
|
+
return By(FOCUSZONE_GRID_BEFORE);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
get _gridAfterButton() {
|
|
159
|
+
return By(FOCUSZONE_GRID_AFTER);
|
|
160
|
+
}
|
|
30
161
|
}
|
|
31
162
|
|
|
32
163
|
export default new FocusZonePageObject();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import NavigateAppPage from '../../common/NavigateAppPage';
|
|
2
|
-
import FocusZonePageObject from '../pages/FocusZonePageObject';
|
|
3
|
-
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
|
|
2
|
+
import FocusZonePageObject, { GridButtonSelector, GridFocusZoneOption } from '../pages/FocusZonePageObject';
|
|
3
|
+
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT, Keys } from '../../common/consts';
|
|
4
4
|
import { Platform } from '../../common/BasePage';
|
|
5
5
|
|
|
6
6
|
// Before testing begins, allow up to 60 seconds for app to open
|
|
@@ -23,3 +23,178 @@ describe('FocusZone Testing Initialization', function () {
|
|
|
23
23
|
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT); // Ensure no asserts popped up
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
|
+
|
|
27
|
+
/* FocusZone Functional Testing
|
|
28
|
+
*
|
|
29
|
+
* This test validates that keyboard navigation using both arrow keys and
|
|
30
|
+
* tab key works, even when modifying how the FocusZone functions.
|
|
31
|
+
*
|
|
32
|
+
* */
|
|
33
|
+
describe('FocusZone Functional Testing', () => {
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
await FocusZonePageObject.scrollToTestElement();
|
|
36
|
+
await FocusZonePageObject.waitForPrimaryElementDisplayed(PAGE_TIMEOUT);
|
|
37
|
+
await FocusZonePageObject.resetTest();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('Navigate bidirectional focuszone by arrow keys - switches focus correctly', async () => {
|
|
41
|
+
// move to 2 with right arrow
|
|
42
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.ARROW_RIGHT]);
|
|
43
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
44
|
+
|
|
45
|
+
// move to 3 with down arrow
|
|
46
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_DOWN]);
|
|
47
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Three)).toBeTruthy();
|
|
48
|
+
|
|
49
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('Navigate horizontal focuszone by arrow keys - switches focus correctly', async () => {
|
|
53
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.SetDirection, 'horizontal');
|
|
54
|
+
// move to 2 with right arrow
|
|
55
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.ARROW_RIGHT]);
|
|
56
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
57
|
+
|
|
58
|
+
// down arrow shouldn't move focus
|
|
59
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_DOWN]);
|
|
60
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
61
|
+
|
|
62
|
+
// left arrow goes back
|
|
63
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Four, [Keys.ARROW_LEFT]);
|
|
64
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Three)).toBeTruthy();
|
|
65
|
+
|
|
66
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('Navigates vertical focuszone by arrow keys - switches focus correctly', async () => {
|
|
70
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.SetDirection, 'vertical');
|
|
71
|
+
|
|
72
|
+
// move to 2 with down arrow
|
|
73
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.ARROW_DOWN]);
|
|
74
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
75
|
+
|
|
76
|
+
// right arrow shouldn't move focus
|
|
77
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_RIGHT]);
|
|
78
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
79
|
+
|
|
80
|
+
// up arrow goes back
|
|
81
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Four, [Keys.ARROW_UP]);
|
|
82
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Three)).toBeTruthy();
|
|
83
|
+
|
|
84
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("Navigates none-direction focuszone by arrow keys - doesn't switch focus", async () => {
|
|
88
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.SetDirection, 'none');
|
|
89
|
+
|
|
90
|
+
// none of these key commands should move
|
|
91
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_DOWN]);
|
|
92
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
93
|
+
|
|
94
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_UP]);
|
|
95
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
96
|
+
|
|
97
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_LEFT]);
|
|
98
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
99
|
+
|
|
100
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_RIGHT]);
|
|
101
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
102
|
+
|
|
103
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('Navigates bi-directional focuszone with 2d navigation - switches focus correctly', async () => {
|
|
107
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.Set2DNavigation, true);
|
|
108
|
+
|
|
109
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.ARROW_DOWN]);
|
|
110
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Four)).toBeTruthy();
|
|
111
|
+
|
|
112
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Four, [Keys.ARROW_RIGHT]);
|
|
113
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Five)).toBeTruthy();
|
|
114
|
+
|
|
115
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("Navigates focuszone with circular navigation off - doesn't switch focus", async () => {
|
|
119
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.ARROW_LEFT]);
|
|
120
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.One)).toBeTruthy();
|
|
121
|
+
|
|
122
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Nine, [Keys.ARROW_RIGHT]);
|
|
123
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Nine)).toBeTruthy();
|
|
124
|
+
|
|
125
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('Navigates focuszone with circular navigation on - switches focus correctly', async () => {
|
|
129
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.SetCircularNavigation, true);
|
|
130
|
+
|
|
131
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.ARROW_LEFT]);
|
|
132
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Nine)).toBeTruthy();
|
|
133
|
+
|
|
134
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Nine, [Keys.ARROW_RIGHT]);
|
|
135
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.One)).toBeTruthy();
|
|
136
|
+
|
|
137
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("Navigates disabled focuszone by arrow keys - doesn't switch focus", async () => {
|
|
141
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.Disable, true);
|
|
142
|
+
|
|
143
|
+
// none of these key commands should move
|
|
144
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_DOWN]);
|
|
145
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
146
|
+
|
|
147
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_UP]);
|
|
148
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
149
|
+
|
|
150
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_LEFT]);
|
|
151
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
152
|
+
|
|
153
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Two, [Keys.ARROW_RIGHT]);
|
|
154
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Two)).toBeTruthy();
|
|
155
|
+
|
|
156
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('Tabs in and out of the FocusZone - switches focus correctly', async () => {
|
|
160
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Before, [Keys.TAB]);
|
|
161
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.One)).toBeTruthy();
|
|
162
|
+
|
|
163
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.One, [Keys.TAB]);
|
|
164
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.After)).toBeTruthy();
|
|
165
|
+
|
|
166
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.After, [Keys.SHIFT, Keys.TAB]);
|
|
167
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Nine)).toBeTruthy();
|
|
168
|
+
|
|
169
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Nine, [Keys.SHIFT, Keys.TAB]);
|
|
170
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Before)).toBeTruthy();
|
|
171
|
+
|
|
172
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('Tabs in and out of the FocusZone with a defaultTabbableElement set - switches focus correctly', async () => {
|
|
176
|
+
// This sets the defaultTabbableElement prop of the FocusZone to be grid button #4. Whenever a user tabs into the zone, button 4 should always be the first to be selected.
|
|
177
|
+
await FocusZonePageObject.configureGridFocusZone(GridFocusZoneOption.UseDefaultTabbableElement, true);
|
|
178
|
+
|
|
179
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Before, [Keys.TAB]);
|
|
180
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Four)).toBeTruthy();
|
|
181
|
+
|
|
182
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Four, [Keys.TAB]);
|
|
183
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.After)).toBeTruthy();
|
|
184
|
+
|
|
185
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.After, [Keys.SHIFT, Keys.TAB]);
|
|
186
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Four)).toBeTruthy();
|
|
187
|
+
|
|
188
|
+
// Key to another button, tab out, and tab back in to make sure the default tabbable element is still the first to be tabbed to
|
|
189
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Four, [Keys.ARROW_RIGHT]);
|
|
190
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Five)).toBeTruthy();
|
|
191
|
+
|
|
192
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Five, [Keys.SHIFT, Keys.TAB]);
|
|
193
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Before)).toBeTruthy();
|
|
194
|
+
|
|
195
|
+
await FocusZonePageObject.sendKeys(GridButtonSelector.Before, [Keys.TAB]);
|
|
196
|
+
await expect(await FocusZonePageObject.gridButtonIsFocused(GridButtonSelector.Four)).toBeTruthy();
|
|
197
|
+
|
|
198
|
+
await expect(await FocusZonePageObject.didAssertPopup()).toBeFalsy(FocusZonePageObject.ERRORMESSAGE_ASSERT);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Keys } from './consts';
|
|
2
2
|
import { TESTPAGE_BUTTONS_SCROLLVIEWER } from '../../TestComponents/Common/consts';
|
|
3
|
+
import { Attribute } from './consts';
|
|
3
4
|
|
|
4
5
|
const DUMMY_CHAR = '';
|
|
5
6
|
export const COMPONENT_SCROLL_COORDINATES = { x: -0, y: -100 }; // These are the offsets. Y is negative because we want the touch to move up (and thus it scrolls down)
|
|
@@ -36,17 +37,17 @@ export class BasePage {
|
|
|
36
37
|
/**************** UI Element Interaction Methods ******************/
|
|
37
38
|
/******************************************************************/
|
|
38
39
|
async getAccessibilityRole(): Promise<string> {
|
|
39
|
-
return await this._primaryComponent.
|
|
40
|
+
return await this.getElementAttribute(await this._primaryComponent, Attribute.AccessibilityRole);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
/* Gets the accessibility label of an UI element given the selector */
|
|
43
44
|
async getAccessibilityLabel(componentSelector: ComponentSelector): Promise<string> {
|
|
44
45
|
switch (componentSelector) {
|
|
45
46
|
case ComponentSelector.Primary:
|
|
46
|
-
return await this._primaryComponent.
|
|
47
|
+
return await this.getElementAttribute(await this._primaryComponent, Attribute.AccessibilityLabel);
|
|
47
48
|
|
|
48
49
|
case ComponentSelector.Secondary:
|
|
49
|
-
return await this._secondaryComponent.
|
|
50
|
+
return await this.getElementAttribute(await this._secondaryComponent, Attribute.AccessibilityLabel);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -66,6 +67,10 @@ export class BasePage {
|
|
|
66
67
|
await this._primaryComponent.click();
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
async getElementAttribute(element: WebdriverIO.Element, attribute: Attribute) {
|
|
71
|
+
return await element.getAttribute(attribute);
|
|
72
|
+
}
|
|
73
|
+
|
|
69
74
|
/* Scrolls until the desired test page's button is displayed. We use the scroll viewer UI element as the point to start scrolling.
|
|
70
75
|
* We use a negative number as the Y-coordinate because that enables us to scroll downwards */
|
|
71
76
|
async scrollToComponentButton(platform: Platform): Promise<void> {
|
package/src/E2E/common/consts.ts
CHANGED
|
@@ -16,6 +16,23 @@ export const TEXT_A11Y_ROLE = 'ControlType.Text';
|
|
|
16
16
|
export const BOOT_APP_TIMEOUT = 60000;
|
|
17
17
|
export const PAGE_TIMEOUT = 15000;
|
|
18
18
|
|
|
19
|
+
export const enum Attribute {
|
|
20
|
+
AccessibilityLabel = 'Name',
|
|
21
|
+
AccessibilityRole = 'ControlType',
|
|
22
|
+
IsEnabled = 'IsEnabled',
|
|
23
|
+
IsFocused = 'HasKeyboardFocus',
|
|
24
|
+
IsRequiredForForm = 'IsRequiredForForm',
|
|
25
|
+
IsTogglePatternAvailable = 'IsTogglePatternAvailable',
|
|
26
|
+
ToggleState = 'Toggle.ToggleState',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const enum AttributeValue {
|
|
30
|
+
on = '1',
|
|
31
|
+
off = '0',
|
|
32
|
+
true = 'True',
|
|
33
|
+
false = 'False',
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
/* Keyboard Key Constants */
|
|
20
37
|
export const enum Keys {
|
|
21
38
|
NULL = '\uE000',
|
|
@@ -9,6 +9,7 @@ import { Picker } from '@react-native-picker/picker';
|
|
|
9
9
|
export interface CollectionItem<T = string> {
|
|
10
10
|
label: string;
|
|
11
11
|
value?: T;
|
|
12
|
+
testID?: string;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export interface MenuPickerProps {
|
|
@@ -17,10 +18,11 @@ export interface MenuPickerProps {
|
|
|
17
18
|
onChange?: (value: any, index?: number) => void;
|
|
18
19
|
collection?: CollectionItem[];
|
|
19
20
|
style?: any;
|
|
21
|
+
testID?: string;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export const MenuPicker: React.FunctionComponent<MenuPickerProps> = (props: MenuPickerProps) => {
|
|
23
|
-
const { prompt, selected, onChange, collection, style } = props;
|
|
25
|
+
const { prompt, selected, onChange, collection, style, testID } = props;
|
|
24
26
|
let selectedItemKey;
|
|
25
27
|
|
|
26
28
|
collection.forEach((item) => {
|
|
@@ -31,13 +33,14 @@ export const MenuPicker: React.FunctionComponent<MenuPickerProps> = (props: Menu
|
|
|
31
33
|
|
|
32
34
|
return (
|
|
33
35
|
<Picker
|
|
36
|
+
testID={testID}
|
|
34
37
|
prompt={prompt}
|
|
35
38
|
selectedValue={selectedItemKey}
|
|
36
39
|
onValueChange={(value: string, index: number) => onChange(value, index)}
|
|
37
40
|
style={{ ...style }}
|
|
38
41
|
>
|
|
39
42
|
{collection.map((item, index) => (
|
|
40
|
-
<Picker.Item label={item.label} key={index} value={item.value} />
|
|
43
|
+
<Picker.Item label={item.label} key={index} value={item.value} testID={item.testID} />
|
|
41
44
|
))}
|
|
42
45
|
</Picker>
|
|
43
46
|
);
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { FocusZoneDirection, FocusZone, MenuButton, Text } from '@fluentui/react-native';
|
|
4
|
+
import { Switch } from '@fluentui-react-native/switch';
|
|
5
|
+
import { ButtonV1 as Button, ButtonProps } from '@fluentui-react-native/button';
|
|
6
|
+
import { commonTestStyles } from '../Common/styles';
|
|
7
|
+
import {
|
|
8
|
+
FOCUSZONE_TEST_COMPONENT,
|
|
9
|
+
FOCUSZONE_DIRECTION_ID,
|
|
10
|
+
FOCUSZONE_TWO_DIM_SWITCH,
|
|
11
|
+
FOCUSZONE_DISABLED_SWITCH,
|
|
12
|
+
FOCUSZONE_CIRCLE_NAV_SWITCH,
|
|
13
|
+
FOCUSZONE_DEFAULT_TABBABLE_SWITCH,
|
|
14
|
+
FOCUSZONE_GRID_BEFORE,
|
|
15
|
+
FOCUSZONE_GRID_AFTER,
|
|
16
|
+
FOCUSZONE_GRID_BUTTON,
|
|
17
|
+
FOCUSZONE_DIRECTION_PICKER,
|
|
18
|
+
} from './consts';
|
|
19
|
+
import { focusZoneTestStyles, GridButton } from './styles';
|
|
20
|
+
|
|
21
|
+
export const FocusZoneDirections: FocusZoneDirection[] = ['bidirectional', 'horizontal', 'vertical', 'none'];
|
|
22
|
+
|
|
23
|
+
type FocusZoneListWrapperProps = {
|
|
24
|
+
beforeID?: string;
|
|
25
|
+
afterID?: string;
|
|
26
|
+
};
|
|
27
|
+
export const FocusZoneListWrapper: React.FunctionComponent<FocusZoneListWrapperProps> = ({ beforeID, afterID, children }) => {
|
|
28
|
+
const buttonProps: ButtonProps = { children: 'Click to Focus', style: focusZoneTestStyles.listWrapperButton };
|
|
29
|
+
return (
|
|
30
|
+
<>
|
|
31
|
+
<Button {...buttonProps} testID={beforeID} />
|
|
32
|
+
{children}
|
|
33
|
+
<Button {...buttonProps} testID={afterID} />
|
|
34
|
+
</>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type GridOfButtonsProps = {
|
|
39
|
+
gridWidth: number;
|
|
40
|
+
gridHeight: number;
|
|
41
|
+
tabRef?: React.RefObject<View>;
|
|
42
|
+
tabbableIdx?: number;
|
|
43
|
+
e2etesting?: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const GridOfButtons: React.FunctionComponent<GridOfButtonsProps> = (props: GridOfButtonsProps) => {
|
|
47
|
+
return (
|
|
48
|
+
<View style={focusZoneTestStyles.dashedBorder}>
|
|
49
|
+
{[...Array(props.gridHeight)].map((_value, heightIndex: number) => {
|
|
50
|
+
return (
|
|
51
|
+
<View key={heightIndex} style={focusZoneTestStyles.focusZoneViewStyle}>
|
|
52
|
+
{[...Array(props.gridWidth)].map((_value, widthIndex: number) => {
|
|
53
|
+
const gridIndex = heightIndex * props.gridWidth + widthIndex + 1;
|
|
54
|
+
return (
|
|
55
|
+
<GridButton
|
|
56
|
+
testID={props.e2etesting ? FOCUSZONE_GRID_BUTTON(gridIndex) : undefined}
|
|
57
|
+
key={widthIndex}
|
|
58
|
+
style={focusZoneTestStyles.focusZoneButton}
|
|
59
|
+
componentRef={gridIndex === props.tabbableIdx ? props.tabRef : undefined}
|
|
60
|
+
>
|
|
61
|
+
<Text>{gridIndex}</Text>
|
|
62
|
+
</GridButton>
|
|
63
|
+
);
|
|
64
|
+
})}
|
|
65
|
+
</View>
|
|
66
|
+
);
|
|
67
|
+
})}
|
|
68
|
+
</View>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const FocusZone2D: React.FunctionComponent = () => {
|
|
73
|
+
const [is2DNav, set2dNav] = React.useState(false);
|
|
74
|
+
const [isDisabled, setDisabled] = React.useState(false);
|
|
75
|
+
const [isCircularNav, setIsCircularNav] = React.useState(false);
|
|
76
|
+
const [useDeffaultTabbableElement, setUseDeffaultTabbableElement] = React.useState(false);
|
|
77
|
+
const [direction, setDirection] = React.useState<FocusZoneDirection>('bidirectional');
|
|
78
|
+
|
|
79
|
+
const tabbableRef = React.useRef(null);
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<View style={commonTestStyles.root}>
|
|
83
|
+
<View style={commonTestStyles.settings}>
|
|
84
|
+
<Text variant="subheaderSemibold" testID={FOCUSZONE_TEST_COMPONENT}>
|
|
85
|
+
FocusZone Direction
|
|
86
|
+
</Text>
|
|
87
|
+
<MenuButton
|
|
88
|
+
testID={FOCUSZONE_DIRECTION_PICKER}
|
|
89
|
+
content={`Current direction: ${direction}`}
|
|
90
|
+
menuItems={FocusZoneDirections.map((dir) => ({
|
|
91
|
+
itemKey: dir,
|
|
92
|
+
text: dir,
|
|
93
|
+
testID: FOCUSZONE_DIRECTION_ID(dir),
|
|
94
|
+
}))}
|
|
95
|
+
onItemClick={(dir) => setDirection(dir as FocusZoneDirection)}
|
|
96
|
+
/>
|
|
97
|
+
<Switch testID={FOCUSZONE_TWO_DIM_SWITCH} label="2D Navigation" checked={is2DNav} onChange={(_, checked) => set2dNav(checked)} />
|
|
98
|
+
<Switch testID={FOCUSZONE_DISABLED_SWITCH} label="Disabled" checked={isDisabled} onChange={(_, checked) => setDisabled(checked)} />
|
|
99
|
+
<Switch
|
|
100
|
+
testID={FOCUSZONE_CIRCLE_NAV_SWITCH}
|
|
101
|
+
label="Circular Navigation"
|
|
102
|
+
checked={isCircularNav}
|
|
103
|
+
onChange={(_, checked) => setIsCircularNav(checked)}
|
|
104
|
+
/>
|
|
105
|
+
<Switch
|
|
106
|
+
testID={FOCUSZONE_DEFAULT_TABBABLE_SWITCH}
|
|
107
|
+
label="Use Default Tabbable Element"
|
|
108
|
+
checked={useDeffaultTabbableElement}
|
|
109
|
+
onChange={(_, checked) => setUseDeffaultTabbableElement(checked)}
|
|
110
|
+
/>
|
|
111
|
+
</View>
|
|
112
|
+
|
|
113
|
+
<FocusZoneListWrapper beforeID={FOCUSZONE_GRID_BEFORE} afterID={FOCUSZONE_GRID_AFTER}>
|
|
114
|
+
<FocusZone
|
|
115
|
+
disabled={isDisabled}
|
|
116
|
+
use2DNavigation={is2DNav}
|
|
117
|
+
focusZoneDirection={direction}
|
|
118
|
+
isCircularNavigation={isCircularNav}
|
|
119
|
+
defaultTabbableElement={useDeffaultTabbableElement ? tabbableRef : undefined}
|
|
120
|
+
>
|
|
121
|
+
<GridOfButtons gridWidth={3} gridHeight={3} tabRef={tabbableRef} tabbableIdx={4} e2etesting />
|
|
122
|
+
</FocusZone>
|
|
123
|
+
</FocusZoneListWrapper>
|
|
124
|
+
</View>
|
|
125
|
+
);
|
|
126
|
+
};
|