UNPKG

expo-updates

Version:

Fetches and manages remotely-hosted assets and updates to your app's JS bundle.

104 lines (85 loc) 3.79 kB
import { by, device, element, waitFor } from 'detox'; import jestExpect from 'expect'; import Server from './utils/server'; import Update from './utils/update'; const projectRoot = process.env.PROJECT_ROOT || process.cwd(); const platform = device.getPlatform(); const protocolVersion = 1; const testElementValueAsync = async (testID: string) => { const attributes: any = await element(by.id(testID)).getAttributes(); return attributes?.text || ''; }; const waitForAppToBecomeVisible = async () => { await waitFor(element(by.id('updateString'))) .toBeVisible() .withTimeout(3000); }; describe('Error recovery tests', () => { afterEach(async () => { await device.uninstallApp(); Server.stop(); }); it('downloads new update before launching, but launches the last non-crashing update', async () => { Server.start(Update.serverPort, protocolVersion, 1000); await Server.serveSignedDirective(Update.getNoUpdateAvailableDirective(), projectRoot); await device.installApp(); await device.launchApp({ newInstance: true, }); const request1 = await Server.waitForUpdateRequest(10000); const request1CurrentUpdateId = request1.headers['expo-current-update-id']; const request1RecentFailedUpdateIds = request1.headers['expo-recent-failed-update-ids']; const embeddedUpdateId = request1.headers['expo-embedded-update-id']; jestExpect(embeddedUpdateId).toBeTruthy(); jestExpect(request1RecentFailedUpdateIds).toBeUndefined(); jestExpect(request1CurrentUpdateId).toEqual(embeddedUpdateId); await waitForAppToBecomeVisible(); await device.terminateApp(); const bundleFilename = 'bundle1.js'; const newNotifyString = 'test-update-crashing'; const hash = await Update.copyBundleToStaticFolder( projectRoot, bundleFilename, newNotifyString, platform ); const manifest = Update.getUpdateManifestForBundleFilename( new Date(), hash, 'test-update-crashing-key', bundleFilename, [], projectRoot ); const failingId = manifest.id; await Server.serveSignedManifest(manifest, projectRoot); // launch app for error recovery try { // Detox on Android may timeout from waiting idling resources because Detox doesn't support reloading the app under the hood await device.launchApp({ newInstance: true, }); } catch {} // we don't check current update ID header or failed update IDs header since the behavior for this request is not defined // (we don't guarantee current update to be set during a crash or the launch failure to have been registered yet) const request2 = await Server.waitForUpdateRequest(10000); const request2EmbeddedUpdateId = request2.headers['expo-embedded-update-id']; jestExpect(embeddedUpdateId).toEqual(request2EmbeddedUpdateId); await device.terminateApp(); // relaunch, it should launch the embedded update since the update being served failed to launch await device.launchApp({ newInstance: true, }); const request3 = await Server.waitForUpdateRequest(10000); const request3CurrentUpdateId = request3.headers['expo-current-update-id']; const request3EmbeddedUpdateId = request3.headers['expo-embedded-update-id']; const request3RecentFailedUpdateIds = request3.headers['expo-recent-failed-update-ids']; jestExpect(embeddedUpdateId).toEqual(request3EmbeddedUpdateId); jestExpect(embeddedUpdateId).toEqual(request3CurrentUpdateId); jestExpect(request3RecentFailedUpdateIds).toEqual(`"${failingId}"`); await waitForAppToBecomeVisible(); const message = await testElementValueAsync('updateString'); jestExpect(message).toBe('test'); await device.terminateApp(); }); });