manishPatwari / WebDriverAgent

A WebDriver server for iOS that runs inside the Simulator.
Other
52 stars 15 forks source link

Device gets disconnected just after clicking on the mobile icon #4

Closed dashweta closed 5 years ago

dashweta commented 6 years ago

Hello, I tried using this repo for the remote access ios devices. I was able to install WebDriverAgent on app and start the node. I am able to see the device on the local server. But when I click on the device it is getting disconnected. Can you help me solve this issue? Following is the log I got :

2018-02-13 15:31:06.288657+0530 WebDriverAgentRunner-Runner[5477:2169917] +[CATransaction synchronize] called within transaction 2018-02-13 15:31:06.339866+0530 WebDriverAgentRunner-Runner[5477:2169917] Running tests... objc[5477]: Class JLRRouteResponse is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5b9e0) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd590). One of the two will be used. Which one is undefined. objc[5477]: Class JLRRouteRequest is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5ba30) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd5e0). One of the two will be used. Which one is undefined. objc[5477]: Class JLRoutes is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5ba80) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd630). One of the two will be used. Which one is undefined. objc[5477]: Class JLRParsingUtilities_RouteSubpath is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5bad0) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd680). One of the two will be used. Which one is undefined. objc[5477]: Class JLRParsingUtilities is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5bb48) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd6f8). One of the two will be used. Which one is undefined. objc[5477]: Class JLRRouteDefinition is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5bb70) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd720). One of the two will be used. Which one is undefined. objc[5477]: Class JLRRouteHandler is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x121f5bbe8) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x121cdd798). One of the two will be used. Which one is undefined. 2018-02-13 15:31:06.676472+0530 WebDriverAgentRunner-Runner[5477:2169917] Continuing to run tests in the background with task ID 1 Test Suite 'Selected tests' started at 2018-02-13 15:31:07.362 Test Suite 'WebDriverAgentLib.framework' started at 2018-02-13 15:31:07.363 Test Suite 'WebDriverAgentLib.framework' passed at 2018-02-13 15:31:07.364. Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds Test Suite 'WebDriverAgentRunner.xctest' started at 2018-02-13 15:31:07.364 Test Suite 'UITestingUITests' started at 2018-02-13 15:31:07.365 Test Case '-[UITestingUITests testSocketRunner]' started. t = 0.00s Start Test at 2018-02-13 15:31:07.366 t = 0.00s Set Up 2018-02-13 15:31:07.370400+0530 WebDriverAgentRunner-Runner[5477:2169917] Built at Feb 13 2018 15:30:52 2018-02-13 15:31:07.482321+0530 WebDriverAgentRunner-Runner[5477:2169917] socket connected 2018-02-13 15:31:30.014068+0530 WebDriverAgentRunner-Runner[5477:2169917] Assertion failure in +[FBApplication fb_activeApplication], /Users/sd82240/Develop/stf-ios/WebDriverAgent-master 2/WebDriverAgentLib/FBApplication.m:43 2018-02-13 15:31:30.017992+0530 WebDriverAgentRunner-Runner[5477:2169917] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Active application instance is not expected to be equal to nil' *** First throw call stack: ( 0 CoreFoundation 0x00000001066aa12b exceptionPreprocess + 171 1 libobjc.A.dylib 0x0000000105d3ef41 objc_exception_throw + 48 2 CoreFoundation 0x00000001066af2f2 +[NSException raise:format:arguments:] + 98 3 Foundation 0x00000001057dfd69 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193 4 WebDriverAgentLib 0x0000000121cadd10 +[FBApplication fb_activeApplication] + 656 5 WebDriverAgentLib 0x0000000121c83f54 -[WebSocketScreenCasting startScreeing:] + 180 6 WebDriverAgentLib 0x0000000121c77c5f 29-[FBWebSocket startWebSocket]_block_invoke.138 + 223 7 SocketIO 0x0000000121de9cf5 _T0So7NSArrayC8SocketIO0B10AckEmitterCIyByy_SayypGAEIxxx_TR + 69 8 SocketIO 0x0000000121de9da2 _T0So7NSArrayC8SocketIO0B10AckEmitterCIyByy_SayypGAEIxxx_TRTA + 66 9 SocketIO 0x0000000121ded841 _T08SocketIO0A12EventHandlerV15executeCallbackySayypG4with_Si0G3AckAA0A8IOClientC0gA0tF + 465 10 SocketIO 0x0000000121de6354 _T08SocketIO0A8IOClientC11handleEventySS_SayypG4dataSb17isInternalMessageSi7withAcktF + 2468 11 SocketIO 0x0000000121de6b55 _T08SocketIO0A8IOClientC12handlePacketyAA0aE0VF + 741 12 SocketIO 0x0000000121e14303 _T08SocketIO0A7ManagerC19_parseEngineMessage33_FEE990CFC310EDF111B3A4D77C509822LLySSF + 1507 13 SocketIO 0x0000000121e13b97 T08SocketIO0A7ManagerC18parseEngineMessageySSFyycfU + 71 14 SocketIO 0x0000000121e13c64 _T08SocketIO0A7ManagerC18parseEngineMessageySSFyycfU_TA + 100 15 SocketIO 0x0000000121dc7b69 _T0Ix_IyB_TR + 41 16 libdispatch.dylib 0x000000010b07d177 _dispatch_call_block_and_release + 12 17 libdispatch.dylib 0x000000010b07e1ba _dispatch_client_callout + 8 18 libdispatch.dylib 0x000000010b0883a4 _dispatch_main_queue_callback_4CF + 1260 19 CoreFoundation 0x000000010666ce39 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9 20 CoreFoundation 0x0000000106631462 CFRunLoopRun + 2402 21 CoreFoundation 0x0000000106630889 CFRunLoopRunSpecific + 409 22 Foundation 0x00000001057376de -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 274 23 WebDriverAgentLib 0x0000000121c77172 -[FBWebSocket startSocket] + 418 24 WebDriverAgentRunner 0x0000000121c59efe -[UITestingUITests testSocketRunner] + 126 25 CoreFoundation 0x000000010662e36c _invoking + 140 26 CoreFoundation 0x000000010662e240 -[NSInvocation invoke] + 320 27 XCTest 0x00000001055efe30 24-[XCTestCase invokeTest]_block_invoke + 591 28 XCTest 0x000000010563917e -[XCUITestContext performInScope:] + 183 29 XCTest 0x00000001055efbd6 -[XCTestCase invokeTest] + 141 30 XCTest 0x00000001055f0b97 26-[XCTestCase performTest:]_block_invoke.369 + 42 31 XCTest 0x000000010563df25 +[XCTContext runInContextForTestCase:block:] + 163 32 XCTest 0x00000001055f0533 -[XCTestCase performTest:] + 608 33 XCTest 0x00000001055ec539 27-[XCTestSuite performTest:]_block_invoke + 363 34 XCTest 0x00000001055ebea0 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 26 35 XCTest 0x00000001055ec09d -[XCTestSuite performTest:] + 239 36 XCTest 0x00000001055ec539 __27-[XCTestSuite performTest:]_block_invoke + 363 37 XCTest 0x00000001055ebea0 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 26 38 XCTest 0x00000001055ec09d -[XCTestSuite performTest:] + 239 39 XCTest 0x00000001055ec539 27-[XCTestSuite performTest:]_block_invoke + 363 40 XCTest 0x00000001055ebea0 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 26 41 XCTest 0x00000001055ec09d -[XCTestSuite performTest:] + 239 42 XCTest 0x000000010564564f 44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke + 40 43 XCTest 0x00000001055ff71a -[XCTestObservationCenter _observeTestExecutionForBlock:] + 475 44 XCTest 0x00000001056454ee -[XCTTestRunSession runTestsAndReturnError:] + 281 45 XCTest 0x00000001055dbaf1 -[XCTestDriver runTestsAndReturnError:] + 314 46 XCTest 0x000000010563d190 _XCTestMain + 619 47 CoreFoundation 0x000000010664d05c CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 48 CoreFoundation 0x000000010663183b CFRunLoopDoBlocks + 203 49 CoreFoundation 0x0000000106631014 __CFRunLoopRun + 1300 50 CoreFoundation 0x0000000106630889 CFRunLoopRunSpecific + 409 51 GraphicsServices 0x00000001099d89c6 GSEventRunModal + 62 52 UIKit 0x0000000106b285d6 UIApplicationMain + 159 53 WebDriverAgentRunner-Runner 0x0000000105548838 WebDriverAgentRunner-Runner + 6200 54 libdyld.dylib 0x000000010aad9d81 start + 1 55 ??? 0x0000000000000005 0x0 + 5 ) libc++abi.dylib: terminating with uncaught exception of type NSException 2018-02-13 15:31:46.752723+0530 WebDriverAgentRunner-Runner[5501:2171367] +[CATransaction synchronize] called within transaction 2018-02-13 15:31:46.815938+0530 WebDriverAgentRunner-Runner[5501:2171367] Running tests... objc[5501]: Class JLRRouteResponse is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a0359e0) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db7590). One of the two will be used. Which one is undefined. objc[5501]: Class JLRRouteRequest is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a035a30) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db75e0). One of the two will be used. Which one is undefined. objc[5501]: Class JLRoutes is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a035a80) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db7630). One of the two will be used. Which one is undefined. objc[5501]: Class JLRParsingUtilities_RouteSubpath is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a035ad0) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db7680). One of the two will be used. Which one is undefined. objc[5501]: Class JLRParsingUtilities is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a035b48) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db76f8). One of the two will be used. Which one is undefined. objc[5501]: Class JLRRouteDefinition is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a035b70) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db7720). One of the two will be used. Which one is undefined. objc[5501]: Class JLRRouteHandler is implemented in both /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/JLRoutes.framework/JLRoutes (0x11a035be8) and /Users/sd82240/Library/Developer/Xcode/DerivedData/WebDriverAgent-gwzmktcudszziaajlduoefatcior/Build/Products/Debug-iphonesimulator/WebDriverAgentLib.framework/WebDriverAgentLib (0x119db7798). One of the two will be used. Which one is undefined. 2018-02-13 15:31:47.328158+0530 WebDriverAgentRunner-Runner[5501:2171367] Continuing to run tests in the background with task ID 1

Restarting after unexpected exit or crash in UITestingUITests/testSocketRunner; summary will include totals from previous launches. Test Suite 'Selected tests' started at 2018-02-13 15:31:47.985 Test Suite 'WebDriverAgentLib.framework' started at 2018-02-13 15:31:47.986 Test Suite 'WebDriverAgentLib.framework' passed at 2018-02-13 15:31:47.987. Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds Test Suite 'WebDriverAgentRunner.xctest' started at 2018-02-13 15:31:47.987 Test Suite 'WebDriverAgentRunner.xctest' failed at 2018-02-13 15:31:47.987. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds Test Suite 'Selected tests' failed at 2018-02-13 15:31:47.988. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.002) seconds

Thanks in advance. Shweta.

shubhankaryash commented 6 years ago

Could you specify the os version and device information.

dashweta commented 6 years ago

I am using ipad. Version 10.3.2. And now it is not detecting the device. I have followed steps as you mentioned. But may be I missed something there. Can you help me out? Also I am able to install the webdriver agent using CLI but from xcode it is building successfully but not launching. Thanks in advance.

shubhankaryash commented 6 years ago

There is some compatibility issue in iOS 10.3.2 with WebDriverAgent. As a result the tests crash when FBApplication returns activeApplication as nil. Could you try updating to iOS 11 and try. That should work. As far as running from xcode is concerned, switch to WebDriverAgentRunner in the top left tab and press Cmd + U. That will run the tests.

dashweta commented 6 years ago

Hello shubhankaryash. You were right about both the things. It is working with ios 11. Can you tell me apart from 10.3.2 which other versions has problem with the WebDriverAgent?

shubhankaryash commented 6 years ago

@dashweta Glad we could sort this out. We have encountered a separate issue in iOS 9.3.5 where there is a crash as we are getting the screenSize with 0 dimensions from the API FBApplication has provided. Not sure if this exists in other iOS 9.x devices. I have used various iOS 10 and 11 devices and haven't faced any issues so far.

dashweta commented 6 years ago

I am getting it on 10.2.1 as well. What versions of 10 is it working?

dashweta commented 6 years ago

Can we install ipa and and run automation through remote access?

manishPatwari commented 6 years ago

@dashweta You can install any iphone application and access it remotely. Can you please elaborate more on what is the your exact requirement?

dashweta commented 6 years ago

Hello, Can we run the automation on ios devices using this web driver agent?

shubhankaryash commented 6 years ago

@dashweta Yeah you can run automated tests as WebDriver is built on top of the XCTest framework which powers automation. If you go through the code the WebDriver exposes APIs which are called from the browser to simulate user actions like click and swipe. You would just need to right new tests and call the methods you want in your automation.

PrasadMadge commented 6 years ago

@shubhankaryash I want to execute my test cases using appium which also internally uses webdriveragent of Facebook. I want to integrate your webdriveragent to appium webdriveragent so that I can leverage this solution.

Can I know what is 8000 port no? what port does webdriveragent server uses internally , can it be customised ?

shubhankaryash commented 6 years ago

@PrasadMadge The url with port no is the location where the node server powering the WebSocket is hosted. The port where you want to host the node server can be specified in the http.js file in the inspector while you need to specify this host url with port to the device trying to connect to this WebSocket in the FBWebSocket.m file.

rpatelxoriant commented 6 years ago

Hello @shubhankaryash

When I run WebDriverAgentRunner, device is getting disconnected after around 5 mins automatically. As mentioned above, there were some iOS compatibility issues so I tried with different iOS versions i.e. 11.3.1, 11.3.2, 11.4. With all of these iOS versions I am getting "Device got disconnected" message in browser.

In UITestingUITests.m file "testSocketRunner" is getting failed always after I run WebDriveAgentRunner, around 5 mins it keeps connected but after that it automatically gets disconnected.

Can you/someone help me and suggest me what needs to be done here?

Thanks

manishPatwari commented 6 years ago

We use Socket to connect Device and the Client. Because of some network problem it is getting disconnected. At our end we never faced such issue. You need to check why network is getting disconnected at your end.

rpatelxoriant commented 6 years ago

@manishPatwari Thanks a lot for your quick reply on previous comment.

As per your reply, I tested on different network as well i.e. other LAN network as well as on Mobile Data as well. But still app gets crashed after around 5-6 mins. After debugging a lot, I found that the app is crashing because it is occupying more than 650MB during these 5-6 mins and after reaching to a certain level, its getting disconnected as the OS terminates the app for exceeding memory usage.

Here I am attaching logs as well as screenshot of memory as well. Can you please check why it is occupying this much amount of memory within 5-6 mins? I have uploaded my current code on a share point and also sharing that link with you as well.

Source Code: https://drive.google.com/file/d/1hX2kNM-AiVOKRM70xcmKZWhcgzZthzzd/view?usp=sharing Device Logs & Screenshots: https://drive.google.com/file/d/1_i3uitwxeDUlXfjR04GRq10J2rwmGarM/view?usp=sharing

Thanks in advance!!!

manishPatwari commented 6 years ago

@rpatelxoriant : Thanks for the details provided. I will look into it as soon as I get time and get back to you.

ghost commented 6 years ago

I'm also seeing this issue, the disconnect happens when device runs out of memory. Any idea what might be causing the issue?

Zoe1808 commented 6 years ago

Device got disconnected in 5~6 mins (iOS 11.4.1) Any update here? @manishPatwari

shubhankaryash commented 6 years ago

https://github.com/socketio/socket.io-client-swift/issues/89 We tried profiling this on instruments. Seems like the objects being emitted through the socket are getting leaked. "I have found that emitting from 1000 async NSOperations within a NSOperationQueue which has maxConcurrentOperationCount = 25 leads to about 20 acks won't be called back due to not safe incrementing of SocketIOClient private currentAck." Looks like the objects which are not getting acks after emission seem to be stuck in limbo and claiming memory. We are trying to figure out a solution. If anybody else here has a clue on how we might get around this, we are welcome for suggestions.

guadaran commented 5 years ago

Hi @shubhankaryash

How about migrate to AZSocketIO as an alternative to socketio?

Unfortunately, it didn’t work. I realized Socket.IO, used to manage socket connection on server, and AZSocketIO were incompatible. I am afraid that version 1.0.0 of AZSocketIO compatible with socket.io was never released

Update

I tried with VPSocketIO instead of socket.io-client-swift. The result is the same, there is a memory leak. As far as I know, the problem is in the pushRawScreenShot method when the screenshot being emitted through the socket. It is rare that both libraries have the same problem, perhaps the problem is elsewhere.

The only and (very very) ugly workaround that I found, is use a

[NSThread sleepForTimeInterval:0.10f];

on the pushRawScreenShot method. With this change, the device is getting disconnected after around 49 mins (on a iPhone SE) but, obviously, it's not a solution.

theopavan commented 5 years ago

Hi @shubhankaryash and @guadaran

I added @autoreleasepool in the pushRawScreenShot method and the memory problem may have been solved ... 45min for now and the memory is around 16mb (and maximum usage was 19mb).

I also kept the [NSThread sleepForTimeInterval:0.10f] because it decreases CPU usage.

-(void) pushRawScreenShot:(SocketIOClient*) clientSocket andOrientation:(UIInterfaceOrientation) orientation andScreenWidth:(CGFloat) screenWidth andScreenHeight:(CGFloat) screenHeight {
  [NSThread sleepForTimeInterval:0.10f];
  NSError *error;
  NSData *screenData = [[XCUIDevice sharedDevice] fb_screenshotWithError:&error withOrientation:orientation andScreenWidth:screenWidth andScreenHeight:screenHeight];
  if(self.rawPrevScreenShotData != nil && [self.rawPrevScreenShotData isEqualToData:screenData]) {
    // Do nothing as the previous screenshot is same as current.
  }
  else {
    self.rawPrevScreenShotData = screenData;
    NSArray *dataArray = [[NSArray alloc] initWithObjects:screenData, nil];
    @autoreleasepool {
      [clientSocket emit:@"rawScreenShot" with: dataArray];
    }
  }
}

And for BAD_ACCESS error, change the rawPrevScreenShotData to retain:

@property (nonatomic, retain) NSData* rawPrevScreenShotData;

I hope this helps with this leaky memory issue ...

shubhankaryash commented 5 years ago

@theopavan Awesome work! I believe autoreleasepool removes the temporary objects from the program's memory footprint. Did you check the memory usage when we just used this(without the sleep on the NSThread) Currently we are pushing screenshots in a while loop which is really heavy as it executes on every CPU clock cycle. Instead of using sleep on the NSThread could we throttle that instead?

theopavan commented 5 years ago

Hi @shubhankaryash, after the autoreleasepool the sleep in NSThread didn't change memory usage, only change CPU usage. Maybe changes in that while is a better idea than the sleep in this case.

guadaran commented 5 years ago

Hi @theopavan,

I was running a test with the suggested changes (as app under test I use the chronometer, in order to keep continually send the screenshots) and after around 15 mins of execution on an iPhone6 (iOS 11.4.1) and around 40 mins on an iPhoneSE (iOS 11.4) , this error appear:

"Message from debugger: Terminated due to memory issue"

captura de pantalla 2018-08-21 a la s 08 31 14

I will try to excute a leaks instruments profile during the execution.

theopavan commented 5 years ago

hi @guadaran , strange ... i tested with an iPad Air (1gb ram ios 11.4) about 2hs and no errors ( memory stable at 16-17mb )... you tried remove the WebDriverAgentRunner from the devices?

guadaran commented 5 years ago

Hi @theopavan,

Thank you for you comment.

I just ran a test in a fresh iPhone 7 Plus (iOS 11.4 - 3GB Ram) without an old WebDriverAgentRunner on it and we have the same issue after around 87 minutes of execution.

captura de pantalla 2018-08-21 a la s 11 13 56

My code:

-(void) pushRawScreenShot:(SocketIOClient*) clientSocket andOrientation:(UIInterfaceOrientation) orientation andScreenWidth:(CGFloat) screenWidth andScreenHeight:(CGFloat) screenHeight {

  NSError *error;
  NSData *screenData = [[XCUIDevice sharedDevice] fb_screenshotWithError:&error withOrientation:orientation andScreenWidth:screenWidth andScreenHeight:screenHeight];
  if(self.rawPrevScreenShotData != nil && [self.rawPrevScreenShotData isEqualToData:screenData]) {
    // Do nothing as the previous screenshot is same as current.
  }
  else {
    self.rawPrevScreenShotData = screenData;
    NSArray *dataArray = [[NSArray alloc] initWithObjects:screenData, nil];
      @autoreleasepool {
        [clientSocket emit:@"rawScreenShot" with: dataArray];
    }
  }
}

-(void) startScreeing: (SocketIOClient*) clientSocket {
  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
  UIInterfaceOrientation interfaceOrientation = FBApplication.fb_activeApplication.interfaceOrientation;
  CGSize screenSize = FBApplication.fb_activeApplication.frame.size;
  CGFloat width = screenSize.width;
  CGFloat height = screenSize.height;

  __weak WebSocketScreenCasting *weakSelf = self;

  dispatch_async(queue, ^{
    while(weakSelf.isSocketConnected) {
      [NSThread sleepForTimeInterval:0.10f];
      WebSocketScreenCasting *strongSelf = weakSelf;
      //[strongSelf pushScreenShot: clientSocket andOrientation:interfaceOrientation andScreenWidth:width andScreenHeight:height];
      [strongSelf pushRawScreenShot: clientSocket andOrientation:interfaceOrientation andScreenWidth:width andScreenHeight:height];
    }
    self.prevScreenShotData = nil;
    self.rawPrevScreenShotData = nil;
  });
}

And for BAD_ACCESS:

@property (nonatomic, retain) NSData* rawPrevScreenShotData;

Environment:

Xcode: Version 9.4.1 (9F2000) WebDriverAgent: Clone from master with the changes that you proposed OS: macOS High Sierra 10.13.5 Device: iPhone 7 Plus (iOS 11.4) App Under Test: Chronometer of com.apple.mobiletimer (In order to send screenshots constantly)

theopavan commented 5 years ago

@guadaran the memory grows linearly? Here don't grows much anymore i tested only with chronometer and more than 2 hours, no memory problems...

captura de tela 2018-08-21 as 11 24 59

guadaran commented 5 years ago

Hi @theopavan,

Well, I just run an antoher test on an iPhone 6 (iOS 11.4) and now I can confirm you that the memory, with your code, is estable, work like a charm!

I realize that on my environment I had the NSZombieEnabled enabled, and when zombies are enabled: "a deallocated object's class is dynamically changed to be _NSZombie, and by default, the memory region is never marked as free..."

Sorry for the bother. Should have checked that first myself.

Thank you for your great work. Regards.

theopavan commented 5 years ago

@guadaran Ops.... i forgot to tell about disable NSZombieEnabled ... i changed in a test some time ago but only this change didn't works and i forgot i had changed that.

manishPatwari commented 5 years ago

@theopavan Great work. Can you please create the PR with your changes ? it will help others to take the advantage of this.

theopavan commented 5 years ago

Hi @manishPatwari, PR created https://github.com/manishPatwari/WebDriverAgent/pull/9