Detox: Detox + Expo + jest : timeout on opening the app
Describe the bug Detox tests timeout waiting for the return of app opening methods. using the detox-expo-helpers , both reloadApp() and device.openUrl({ url }) hang while waiting for the device response.
It looks like the Device Driver deliverPayload does not return.
To Reproduce
- I have tested this issue on the latest Detox release and it still reproduces
Here is a repo (basically I just ran expo init and detox init -r jest) https://github.com/jeromecornet/expotest
You will note that device.launchApp without a url returns, but does not with a url launch parameter.
Also I can use the standalone app (not via the expo client) and it works fine, this seems to be specific to the expo client.
Expected behavior Both launch methods should return.
Environment (please complete the following information):
- Detox: 12.10.2
- React Native: 0.57.1 (from expo sdk 32.0.0)
- Node: 6.7.0
- Device: iOS simulator, iPhone 8
- Xcode: 10.2.1
- iOS: 12.1
- macOS: 10.14.5
with expo 32.0.0
Device and Verbose Detox Logs
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBootDevice({ coldBoot: false,
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4' })
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeUninstallApp({ deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
bundleId: 'host.exp.Exponent' })
detox[54371] DEBUG: [exec.js/EXEC_CMD, #3] /usr/bin/xcrun simctl uninstall 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent
detox[54371] DEBUG: [exec.js/EXEC_TRY, #3] Uninstalling host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #3]
detox[54371] DEBUG: [exec.js/EXEC_SUCCESS, #3] host.exp.Exponent uninstalled
detox[54371] DEBUG: [exec.js/EXEC_CMD, #4] /usr/bin/xcrun simctl install 2F0E2EDF-A080-4757-90C4-976F1445D7C4 "/Users/jeromecornet/src/expotest/bin/expo.app"
detox[54371] DEBUG: [exec.js/EXEC_TRY, #4] Installing /Users/jeromecornet/src/expotest/bin/expo.app...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #4]
detox[54371] DEBUG: [exec.js/EXEC_SUCCESS, #4] /Users/jeromecornet/src/expotest/bin/expo.app installed
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeTerminateApp({ deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
bundleId: 'host.exp.Exponent' })
detox[54371] DEBUG: [exec.js/EXEC_CMD, #5] /usr/bin/xcrun simctl terminate 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent
detox[54371] DEBUG: [exec.js/EXEC_TRY, #5] Terminating host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #5]
detox[54371] DEBUG: [exec.js/EXEC_SUCCESS, #5] host.exp.Exponent terminated
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeLaunchApp({ bundleId: 'host.exp.Exponent',
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
launchArgs:
{ detoxServer: 'ws://localhost:58963',
detoxSessionId: 'e36ef041-2bde-00df-d586-44b10a2a6098' } })
detox[54371] DEBUG: [exec.js/EXEC_CMD, #6] /bin/cat /dev/null >/Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.out 2>/Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.err && SIMCTL_CHILD_DYLD_INSERT_LIBRARIES="/Users/jeromecornet/Library/Detox/ios/0f0da01849237f5e3552f9c24f9315745fb4c726/Detox.framework/Detox" /usr/bin/xcrun simctl launch --stdout=/tmp/detox.last_launch_app_log.out --stderr=/tmp/detox.last_launch_app_log.err 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent --args -detoxServer "ws://localhost:58963" -detoxSessionId "e36ef041-2bde-00df-d586-44b10a2a6098"
detox[54371] DEBUG: [exec.js/EXEC_TRY, #6] Launching host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #6] host.exp.Exponent: 54408
detox[54371] INFO: [AppleSimUtils.js] host.exp.Exponent launched. The stdout and stderr logs were recreated, you can watch them with:
tail -F /Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.{out,err}
detox[54408] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onLaunchApp({ bundleId: 'host.exp.Exponent',
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
launchArgs:
{ detoxServer: 'ws://localhost:58963',
detoxSessionId: 'e36ef041-2bde-00df-d586-44b10a2a6098' },
pid: 54408 })
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"isReady","params":{},"messageId":-1000}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=isReady (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] DEBUG: [DetoxServer.js/CANNOT_FORWARD] role=testee not connected, cannot fw action (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] DEBUG: [DetoxServer.js/LOGIN] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] DEBUG: [DetoxServer.js/LOGIN_SUCCESS] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=testee action=ready (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_MESSAGE] {"type":"ready","messageId":-1000,"params":{}}
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"waitForActive","params":{},"messageId":1}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=waitForActive (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=testee action=waitForActiveDone (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_MESSAGE] {"type":"waitForActiveDone","messageId":1,"params":{}}
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeAll()
Example: should load the app
detox[54371] TRACE: [Detox.js/DETOX_BEFORE_EACH] running test: "Example should load the app"
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeEach({ title: 'should load the app',
fullName: 'Example should load the app',
status: 'running' })
console.log e2e/firstTest.spec.js:6
Lauching using reloadApp
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeTerminateApp({ deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
bundleId: 'host.exp.Exponent' })
detox[54371] DEBUG: [exec.js/EXEC_CMD, #7] /usr/bin/xcrun simctl terminate 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent
detox[54371] DEBUG: [exec.js/EXEC_TRY, #7] Terminating host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #7]
detox[54371] DEBUG: [exec.js/EXEC_SUCCESS, #7] host.exp.Exponent terminated
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeLaunchApp({ bundleId: 'host.exp.Exponent',
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
launchArgs:
{ detoxServer: 'ws://localhost:58963',
detoxSessionId: 'e36ef041-2bde-00df-d586-44b10a2a6098',
EXKernelDisableNuxDefaultsKey: true,
detoxURLBlacklistRegex:
'\\("http://192.168.86.24:19005/onchange","https://e.crashlytics.com/spi/v2/events"\\)',
detoxURLOverride: 'exp://192.168.86.24:19004',
detoxSourceAppOverride: 'host.exp.exponent' } })
detox[54371] DEBUG: [DetoxServer.js/DISCONNECT] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] DEBUG: [exec.js/EXEC_CMD, #8] /bin/cat /dev/null >/Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.out 2>/Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.err && SIMCTL_CHILD_DYLD_INSERT_LIBRARIES="/Users/jeromecornet/Library/ExpoDetoxHook/ios/d49fa2ddb665bfbaeb7e286b34efc73912f59c66/ExpoDetoxHook.framework/ExpoDetoxHook:/Users/jeromecornet/Library/Detox/ios/0f0da01849237f5e3552f9c24f9315745fb4c726/Detox.framework/Detox" /usr/bin/xcrun simctl launch --stdout=/tmp/detox.last_launch_app_log.out --stderr=/tmp/detox.last_launch_app_log.err 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent --args -detoxServer "ws://localhost:58963" -detoxSessionId "e36ef041-2bde-00df-d586-44b10a2a6098" -EXKernelDisableNuxDefaultsKey "true" -detoxURLBlacklistRegex "\("http://192.168.86.24:19005/onchange","https://e.crashlytics.com/spi/v2/events"\)" -detoxURLOverride "exp://192.168.86.24:19004" -detoxSourceAppOverride "host.exp.exponent"
detox[54371] DEBUG: [exec.js/EXEC_TRY, #8] Launching host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #8] host.exp.Exponent: 54435
detox[54371] INFO: [AppleSimUtils.js] host.exp.Exponent launched. The stdout and stderr logs were recreated, you can watch them with:
tail -F /Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.{out,err}
detox[54435] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onLaunchApp({ bundleId: 'host.exp.Exponent',
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
launchArgs:
{ detoxServer: 'ws://localhost:58963',
detoxSessionId: 'e36ef041-2bde-00df-d586-44b10a2a6098',
EXKernelDisableNuxDefaultsKey: true,
detoxURLBlacklistRegex:
'\\("http://192.168.86.24:19005/onchange","https://e.crashlytics.com/spi/v2/events"\\)',
detoxURLOverride: 'exp://192.168.86.24:19004',
detoxSourceAppOverride: 'host.exp.exponent' },
pid: 54435 })
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"isReady","params":{},"messageId":-1000}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=isReady (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] DEBUG: [DetoxServer.js/CANNOT_FORWARD] role=testee not connected, cannot fw action (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] DEBUG: [DetoxServer.js/LOGIN] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] DEBUG: [DetoxServer.js/LOGIN_SUCCESS] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
Example: should load the app [FAIL]
Example: should open the app URL
detox[54371] TRACE: [Detox.js/DETOX_AFTER_EACH] failed test: "Example should load the app"
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onAfterEach({ title: 'should load the app',
fullName: 'Example should load the app',
status: 'failed' })
detox[54371] TRACE: [Detox.js/DETOX_BEFORE_EACH] running test: "Example should open the app URL"
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeEach({ title: 'should open the app URL',
fullName: 'Example should open the app URL',
status: 'running' })
console.log e2e/firstTest.spec.js:13
Lauching expo
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeTerminateApp({ deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
bundleId: 'host.exp.Exponent' })
detox[54371] DEBUG: [exec.js/EXEC_CMD, #9] /usr/bin/xcrun simctl terminate 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent
detox[54371] DEBUG: [exec.js/EXEC_TRY, #9] Terminating host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #9]
detox[54371] DEBUG: [exec.js/EXEC_SUCCESS, #9] host.exp.Exponent terminated
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onBeforeLaunchApp({ bundleId: 'host.exp.Exponent',
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
launchArgs:
{ detoxServer: 'ws://localhost:58963',
detoxSessionId: 'e36ef041-2bde-00df-d586-44b10a2a6098',
EXKernelDisableNuxDefaultsKey: true } })
detox[54371] DEBUG: [DetoxServer.js/DISCONNECT] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] DEBUG: [exec.js/EXEC_CMD, #10] /bin/cat /dev/null >/Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.out 2>/Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.err && SIMCTL_CHILD_DYLD_INSERT_LIBRARIES="/Users/jeromecornet/Library/ExpoDetoxHook/ios/d49fa2ddb665bfbaeb7e286b34efc73912f59c66/ExpoDetoxHook.framework/ExpoDetoxHook:/Users/jeromecornet/Library/Detox/ios/0f0da01849237f5e3552f9c24f9315745fb4c726/Detox.framework/Detox" /usr/bin/xcrun simctl launch --stdout=/tmp/detox.last_launch_app_log.out --stderr=/tmp/detox.last_launch_app_log.err 2F0E2EDF-A080-4757-90C4-976F1445D7C4 host.exp.Exponent --args -detoxServer "ws://localhost:58963" -detoxSessionId "e36ef041-2bde-00df-d586-44b10a2a6098" -EXKernelDisableNuxDefaultsKey "true"
detox[54371] DEBUG: [exec.js/EXEC_TRY, #10] Launching host.exp.Exponent...
detox[54371] TRACE: [exec.js/EXEC_SUCCESS, #10] host.exp.Exponent: 54511
detox[54371] INFO: [AppleSimUtils.js] host.exp.Exponent launched. The stdout and stderr logs were recreated, you can watch them with:
tail -F /Users/jeromecornet/Library/Developer/CoreSimulator/Devices/2F0E2EDF-A080-4757-90C4-976F1445D7C4/data/tmp/detox.last_launch_app_log.{out,err}
detox[54511] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onLaunchApp({ bundleId: 'host.exp.Exponent',
deviceId: '2F0E2EDF-A080-4757-90C4-976F1445D7C4',
launchArgs:
{ detoxServer: 'ws://localhost:58963',
detoxSessionId: 'e36ef041-2bde-00df-d586-44b10a2a6098',
EXKernelDisableNuxDefaultsKey: true },
pid: 54511 })
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"isReady","params":{},"messageId":-1000}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=isReady (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] DEBUG: [DetoxServer.js/CANNOT_FORWARD] role=testee not connected, cannot fw action (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] DEBUG: [DetoxServer.js/LOGIN] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] DEBUG: [DetoxServer.js/LOGIN_SUCCESS] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=testee action=ready (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_MESSAGE] {"type":"ready","messageId":-1000,"params":{}}
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"waitForActive","params":{},"messageId":2}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=waitForActive (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=testee action=waitForActiveDone (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_MESSAGE] {"type":"waitForActiveDone","messageId":2,"params":{}}
console.log e2e/firstTest.spec.js:20
Opening app URL: exp://192.168.86.24:19004
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"deliverPayload","params":{"url":"exp://192.168.86.24:19004"},"messageId":3}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=deliverPayload (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
Example: should open the app URL [FAIL]
detox[54371] TRACE: [Detox.js/DETOX_AFTER_EACH] failed test: "Example should open the app URL"
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onAfterEach({ title: 'should open the app URL',
fullName: 'Example should open the app URL',
status: 'failed' })
detox[54371] TRACE: [ArtifactsManager.js/LIFECYCLE] artifactsManager.onAfterAll()
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_SEND] {"type":"cleanup","params":{"stopRunner":true},"messageId":4}
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=tester action=cleanup (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [DetoxServer.js/MESSAGE] role=testee action=cleanupDone (sessionId=e36ef041-2bde-00df-d586-44b10a2a6098)
detox[54371] TRACE: [AsyncWebSocket.js/WEBSOCKET_MESSAGE] {"type":"cleanupDone","messageId":4,"params":{}}
FAIL e2e/firstTest.spec.js (258.305s)
Example
✕ should load the app (120243ms)
✕ should open the app URL (120003ms)
● Example › should load the app
Timeout - Async callback was not invoked within the 120000ms timeout specified by jest.setTimeout.
8 | console.log("App launched")
9 | await expect(element(by.text('Open up App.js to start working on your app!'))).toBeVisible();
> 10 | });
| ^
11 |
12 | it('should open the app URL', async () => {
13 | console.log("Lauching expo")
at new Spec (../node_modules/@jest/core/node_modules/jest-jasmine2/build/jasmine/Spec.js:116:22)
at Suite.<anonymous> (firstTest.spec.js:10:3)
at Object.<anonymous> (firstTest.spec.js:9:1)
● Example › should open the app URL
Timeout - Async callback was not invoked within the 120000ms timeout specified by jest.setTimeout.
at new Spec (../node_modules/@jest/core/node_modules/jest-jasmine2/build/jasmine/Spec.js:116:22)
at Suite.<anonymous> (firstTest.spec.js:31:3)
at Object.<anonymous> (firstTest.spec.js:9:1)
detox[54371] DEBUG: [DetoxServer.js/DISCONNECT] role=tester, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54371] DEBUG: [DetoxServer.js/DISCONNECT] role=testee, sessionId=e36ef041-2bde-00df-d586-44b10a2a6098
detox[54369] ERROR: [cli.js] Error: Command failed: node_modules/.bin/jest --config=e2e/config.json --maxWorkers=1 '--testNamePattern=^((?!:android:).)*$' "e2e"
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 6
- Comments: 38 (15 by maintainers)
This also happens to me - Expo only works with detox 12.3.0. I made a sample project - this may help who ever is trying to solve this (@LeoNatan): https://github.com/yaron1m/expo-detox-typescript-example
Hi @brookemitchell I confirm because I’m using this patch and my e2e tests was fix
detox+13.3.1.patch
:Well think I found the offending commit https://github.com/wix/Detox/commit/32be293774383d631d0938300175204d4222dd13
Reverting this commit works for me with the latest detox, can any other expo users confirm?
I think that change broke passing in a url blacklist on launch?
From the detox docs for device-launch
It seems after the commit passing a blacklistregex to launchArgs like
(see: detox-expo-helper#L105) to DetoxManager.m no longer works? Sorry I don’t have the obj-c debugging chops to be certain right now.
Please use StackOverflow for general usage questions. This question is specifically about Expo.
Thanks @LeoNatan That log was massive so I removed consecutive duplicate lines
Here’s what I got:
The output of detox test shows
So it looks like it’s not detecting that the app has finished loading.
Now on the other hand, I managed to find a workaround: launch expo without any app, set the live reload blacklist then call device.openURL This test is now passing: https://github.com/jeromecornet/expotest/blob/b09b2b65ed007fdacb1a3a88150452694d189616/e2e/firstTest.spec.js#L31-L47 (although this specific version uses detoxPrintBusyIdleResources: ‘YES’ which you don’t need)
In my prior tests, the device.openURL would fail because I did not specify the Blacklist for live reload and it got stuck waiting for the /onchange call to be dealt with (which I discovered using the EarlGreyStatistics)
Confirming 12.3.0 fixes the issue for me, don’t have any solutions at this time.
It actually does the same in ejected app #1187