also looking at this
test(ios): tap a real pushed notification that launches the app, and judge what the page gets
#257
5 files
+308
-10
| @@ -15,6 +15,8 @@ | ||
| 15 | 15 | <h1 id="headline">Craft mobile E2E</h1> |
| 16 | 16 | <ul id="results"></ul> |
| 17 | 17 | <p id="deeplink"></p> |
| 18 | <p id="notification-permission"></p> | |
| 19 | <p id="notification"></p> | |
| 18 | 20 | <script> |
| 19 | 21 | // The page drives itself and reports through the bridge's own `log` action, |
| 20 | 22 | // which is the one channel both runtimes already forward off-device: iOS |
| @@ -36,6 +38,13 @@ | ||
| 36 | 38 | var dispatchedLinks = [] |
| 37 | 39 | window.addEventListener('craftDeepLink', function (event) { dispatchedLinks.push(event.detail || {}) }) |
| 38 | 40 | |
| 41 | // Every notification tap the native side dispatches, counted the same way, | |
| 42 | // so a missing tap can be put on the right side of the bridge: none here | |
| 43 | // means the app never handed it over, one here and none through onTap | |
| 44 | // means the page's replay lost it. | |
| 45 | var dispatchedTaps = 0 | |
| 46 | window.addEventListener('craftNotificationResponse', function () { dispatchedTaps++ }) | |
| 47 | ||
| 39 | 48 | var NONCE = '__CRAFT_E2E_NONCE__' |
| 40 | 49 | // Which platform the harness built this leg for. Substituted in from |
| 41 | 50 | // outside, because the page comparing window.craft.platform against a |
| @@ -487,6 +496,40 @@ | ||
| 487 | 496 | setTimeout(report, 250) |
| 488 | 497 | } |
| 489 | 498 | |
| 499 | // #255: a tap on a push that launches the app reaches a page that | |
| 500 | // subscribes late, through notifications.onTap. | |
| 501 | // | |
| 502 | // The harness does on iOS what a person does, from an XCUITest: it opens | |
| 503 | // the permission link and allows the prompt, kills the app, sends a real | |
| 504 | // push with `simctl push`, and taps the banner. The page subscribes after | |
| 505 | // the suite, seconds after the bridge appeared, and reports what it was | |
| 506 | // handed. On any other launch it was handed nothing, and says so. | |
| 507 | // | |
| 508 | // Permission is asked for only when the link asks, because nothing | |
| 509 | // answers the prompt on the launches simctl makes. iOS only: Android has | |
| 510 | // no tap path to test yet. | |
| 511 | function probeNotifications() { | |
| 512 | if (window.craft.platform !== 'ios') return | |
| 513 | var launch = dispatchedLinks.filter(function (detail) { return detail.initial === true })[0] || null | |
| 514 | if (launch && launch.url.indexOf('://e2e/notify') !== -1) { | |
| 515 | var said = function (text) { document.getElementById('notification-permission').textContent = 'CRAFT-E2E-NOTIFY-PERMISSION ' + text } | |
| 516 | window.craft.permissions.request('notifications').then(said, function (error) { said('rejected ' + describeError(error).message) }) | |
| 517 | } | |
| 518 | var onTap = window.craft.notifications && window.craft.notifications.onTap | |
| 519 | var seen = { dispatched: 0, taps: [], onTap: typeof onTap, unsubscribe: null } | |
| 520 | if (typeof onTap === 'function') { | |
| 521 | seen.unsubscribe = typeof window.craft.notifications.onTap(function (detail) { seen.taps.push(detail || {}) }) | |
| 522 | } | |
| 523 | // Long enough for a replay, or a second delivery, to have arrived. | |
| 524 | setTimeout(function () { | |
| 525 | seen.dispatched = dispatchedTaps | |
| 526 | var line = 'CRAFT-E2E-NOTIFICATION ' + JSON.stringify(seen) | |
| 527 | document.getElementById('notification').textContent = line | |
| 528 | try { console.log(line) } catch (ignored) {} | |
| 529 | try { if (window.craft && window.craft.log) window.craft.log(line) } catch (ignored) {} | |
| 530 | }, 1500) | |
| 531 | } | |
| 532 | ||
| 490 | 533 | function waitForBridge(attempt) { |
| 491 | 534 | if (window.craft && window.craft.getDeviceInfo) return Promise.resolve(true) |
| 492 | 535 | if (attempt >= 150) return Promise.resolve(false) |
| @@ -517,6 +560,7 @@ | ||
| 517 | 560 | emit({ event: 'done', passed: passed, failed: failed }) |
| 518 | 561 | document.getElementById('headline').textContent = failed ? 'FAILED' : 'PASSED' |
| 519 | 562 | probeDeepLinks() |
| 563 | probeNotifications() | |
| 520 | 564 | return |
| 521 | 565 | } |
| 522 | 566 | |