Skip to content

Commit 74ef629

Browse files
committed
test(appium): fix iOS system alert handling
1 parent b636fd2 commit 74ef629

3 files changed

Lines changed: 30 additions & 17 deletions

File tree

appium/scripts/run-local.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ EOF
171171
info "Installing Flutter dependencies..."
172172
(cd "$FLUTTER_DIR" && flutter pub get)
173173

174-
info "Installing CocoaPods..."
175-
(cd "$DEMO_DIR/ios" && pod install)
174+
# info "Installing CocoaPods..."
175+
# (cd "$DEMO_DIR/ios" && pod install)
176176

177177
info "Building debug .app for simulator (this may take a few minutes)..."
178178
(cd "$DEMO_DIR" && flutter build ios --simulator --debug)

appium/tests/helpers/app.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs';
22
import { resolve, dirname } from 'node:path';
33
import { fileURLToPath } from 'node:url';
44

5-
import { byTestId, byText, getPlatform, getSdkType, getTestExternalId } from './selectors.js';
5+
import { byTestId, byText, getPlatform, getTestExternalId } from './selectors.js';
66

77
const __dirname = dirname(fileURLToPath(import.meta.url));
88
const tooltipContent = JSON.parse(
@@ -128,13 +128,24 @@ async function clickFirstExisting(selectors: string[], timeout = 1500) {
128128
return false;
129129
}
130130

131+
/**
132+
* System permission dialogs live under SpringBoard on iOS, so treat them like
133+
* regular UI and click the expected button if it is visible.
134+
*/
135+
async function clickIosSystemAlertButton(buttonLabel: string) {
136+
await driver.updateSettings({ defaultActiveApplication: 'com.apple.springboard' });
137+
try {
138+
return await clickFirstExisting([
139+
`-ios class chain:**/XCUIElementTypeButton[\`label == "${buttonLabel}"\`]`,
140+
]);
141+
} finally {
142+
await driver.updateSettings({ defaultActiveApplication: 'auto' });
143+
}
144+
}
145+
131146
export async function allowNotifications() {
132147
if (driver.isIOS) {
133-
await driver.updateSettings({
134-
acceptAlertButtonSelector: '**/XCUIElementTypeButton[`label == "Allow"`]',
135-
});
136-
await driver.acceptAlert();
137-
return true;
148+
return clickIosSystemAlertButton('Allow');
138149
}
139150

140151
return clickFirstExisting([
@@ -146,11 +157,7 @@ export async function allowNotifications() {
146157

147158
export async function allowLocation() {
148159
if (driver.isIOS) {
149-
await driver.updateSettings({
150-
acceptAlertButtonSelector: '**/XCUIElementTypeButton[`label == "Allow While Using App"`]',
151-
});
152-
await driver.acceptAlert();
153-
return true;
160+
return clickIosSystemAlertButton('Allow While Using App');
154161
}
155162

156163
return clickFirstExisting([
@@ -165,9 +172,9 @@ export async function allowLocation() {
165172
/**
166173
* Wait for the app to fully launch and the home screen to be visible.
167174
*
168-
* System permission dialogs are handled automatically by Appium via the
169-
* `autoGrantPermissions` (Android) and `autoAcceptAlerts` (iOS) capabilities,
170-
* so no explicit dialog handling is needed here.
175+
* Accepts the notification permission dialog if present. Safe to call multiple
176+
* times: on iOS the prompt only appears on first launch after install, and
177+
* `allowNotifications` no-ops when no alert is showing.
171178
*/
172179
export async function waitForAppReady(opts: { skipLogin?: boolean } = {}) {
173180
const { skipLogin = false } = opts;

appium/tests/specs/04_alias.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { checkTooltip, expectPairInSection, scrollToEl, typeInto, waitForAppReady } from '../helpers/app';
1+
import {
2+
checkTooltip,
3+
expectPairInSection,
4+
scrollToEl,
5+
typeInto,
6+
waitForAppReady,
7+
} from '../helpers/app';
28
import { byTestId, byText } from '../helpers/selectors.js';
39

410
describe('Aliases', () => {

0 commit comments

Comments
 (0)