Documentation Index
Fetch the complete documentation index at: https://docs.qawolf.com/llms.txt
Use this file to discover all available pages before exploring further.
Use device.injectBeacon() to simulate the device detecting a nearby iBeacon, triggering CLLocationManager callbacks in your app as if real hardware were present. Pushing a .region file triggers a region-entry callback; also pushing a .beacon file triggers ranging callbacks.
See the iOS Device Reference for the full injectBeacon API.
Examples
Region entry and ranging
const cleanup = await device.injectBeacon(driver, "com.example.app", {
uuid: "8613BEAD-5465-4515-8F9C-AEEA717484C9",
beacons: [{ major: 1, minor: 7 }],
});
// assert your app responded to the beacon event
await cleanup();
Region entry only (no ranging)
Omit the beacons array to trigger only a region-entry event.
const cleanup = await device.injectBeacon(driver, "com.example.app", {
uuid: "e62c96fd-014a-454f-9b41-32245d802bb3",
});
// assert your app responded to the region entry
await cleanup();
When to use
- Your app uses iBeacon proximity for retail check-ins, loyalty triggers, or location-based promotions.
- Your app uses indoor navigation or asset tracking via Bluetooth beacons.
- Your app responds to beacon region entry or exit events.
- Your test needs to verify ranging callbacks with specific major/minor values.
Location permissions
iBeacons require location permissions. Two important caveats:
autoAcceptAlerts chooses “Ask Next Time” for location dialogs. If the permission dialog appears, Appium will not choose “Always Allow” — and there is no way to change it after the fact.
Background location access cannot be auto-accepted. If your app requires “Change to Always Allow” for background beacon detection, you must handle the dialog manually using respectSystemAlerts: true:
const { driver: d } = await launch({
bundleId: "com.example.app",
respectSystemAlerts: true,
});
const allowBtn = d.$(`//XCUIElementTypeButton[@name='Allow']`);
if (await allowBtn.isExisting()) {
await allowBtn.click();
}
respectSystemAlerts: true may slow down Appium performance. Use it only when you need to interact with system dialogs manually.
Full sample test
import { device, flow } from "@qawolf/flows/ios";
export default flow(
"Test beacon proximity",
{ target: "iOS - iPhone 15 (iOS 26)", launch: true },
async ({ driver, test }) => {
await test("inject beacon and verify app response", async () => {
// Arrange
const allowBtn = driver.$(`//XCUIElementTypeButton[@name='Allow']`);
if (await allowBtn.isExisting()) {
await allowBtn.click();
}
await driver.$(`//XCUIElementTypeStaticText[@name='Nearby']`).waitForDisplayed({ timeout: 10_000 });
// Act
const cleanup = await device.injectBeacon(driver, process.env.BUNDLE_ID, {
uuid: "8613BEAD-5465-4515-8F9C-AEEA717484C9",
beacons: [{ major: 1, minor: 7 }],
});
// Assert
await driver
.$(`//XCUIElementTypeStaticText[@name='Beacon Detected']`)
.waitForDisplayed({ timeout: 10_000 });
await cleanup();
});
},
);