fix: Qibla not detecting device compass on iOS and Android
Two real bugs, both explaining 'didn't detect compass': 1. iOS: DeviceOrientationEvent.requestPermission() was called *after* the async geolocation round-trip resolved. Safari's user-activation grant for sensor permissions expires almost immediately, so by the time a GPS fix comes back (often several seconds), the permission call silently fails with no prompt ever shown. Now requested synchronously inside the button's click handler, before geolocation starts. 2. Android: the heading was only accepted when e.absolute === true, but many Android browsers fire plain 'deviceorientation' with absolute:false even though alpha is a perfectly usable heading — compass detection silently never succeeded on those devices at all. Now accepts alpha regardless of the absolute flag, falling back to it when webkitCompassHeading (iOS) isn't present. Also fixed a duplicate-listener bug: clicking 'Refresh location' repeatedly re-registered deviceorientation listeners without removing the previous ones, stacking duplicates on every retry. Verified live: dispatched a synthetic non-absolute deviceorientation event (the exact Android failure shape) against the deployed app — compass detection now activates correctly where it previously stayed silently stuck on the no-sensor fallback. Added as a permanent regression assertion in e2e-khairat-lifestyle.cjs (16/16).
This commit is contained in:
@@ -60,6 +60,22 @@ async function main() {
|
||||
const distanceVisible = await page.locator('.distance-note', { hasText: 'km to Makkah' }).isVisible().catch(() => false);
|
||||
record('Qibla: shows distance to Makkah', distanceVisible);
|
||||
|
||||
// Regression guard: many Android browsers fire plain 'deviceorientation'
|
||||
// with absolute:false even though alpha is a usable heading — a prior
|
||||
// version required absolute:true and silently never detected the compass
|
||||
// on those devices. Simulate exactly that event shape.
|
||||
const staticNoteBeforeSensor = await page.locator('.static-note').isVisible().catch(() => false);
|
||||
record('Qibla: shows the no-sensor fallback note before any orientation event', staticNoteBeforeSensor);
|
||||
await page.evaluate(() => {
|
||||
const evt = new Event('deviceorientation');
|
||||
Object.defineProperty(evt, 'alpha', { value: 90 });
|
||||
Object.defineProperty(evt, 'absolute', { value: false });
|
||||
window.dispatchEvent(evt);
|
||||
});
|
||||
await page.waitForTimeout(500);
|
||||
const staticNoteAfterSensor = await page.locator('.static-note').isVisible().catch(() => false);
|
||||
record('Qibla: accepts a non-absolute deviceorientation event as a valid compass reading (Android)', !staticNoteAfterSensor);
|
||||
|
||||
// ── Prayer Times ──
|
||||
await gotoTab(page, 'Prayer Times');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
Reference in New Issue
Block a user