PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/appium/docs/en/advanced-concepts/hybrid.md

https://gitlab.com/freedmpure/studyGit
Markdown | 217 lines | 163 code | 54 blank | 0 comment | 0 complexity | 1434ff7043ffdec490915a2c057852c0 MD5 | raw file
  1. ## Automating hybrid apps
  2. One of the core principles of Appium is that you shouldn't have to change
  3. your app to test it. In line with that methodology, it is possible to test
  4. hybrid web apps (e.g., the "UIWebView" elements in an iOS app) the same way
  5. you can with Selenium for web apps. There is a bit of technical complexity
  6. required so that Appium knows whether you want to automate the native aspects
  7. of the app or the web views, but thankfully, we can stay within the
  8. WebDriver protocol for everything.
  9. Here are the steps required to talk to a web view in your Appium test:
  10. 1. Navigate to a portion of your app where a web view is active
  11. 1. Call [GET session/:sessionId/contexts](https://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile)
  12. 1. This returns a list of contexts we can access, like 'NATIVE_APP' or 'WEBVIEW_1'
  13. 1. Call [POST session/:sessionId/context](https://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile)
  14. with the id of the context you want to access
  15. 1. (This puts your Appium session into a mode where all commands are
  16. interpreted as being intended for automating the web view,
  17. rather than the native portion of the app. For example,
  18. if you run getElementByTagName, it will operate on the DOM of the web
  19. view, rather than return UIAElements. Of course,
  20. certain WebDriver methods only make sense in one context or another,
  21. so in the wrong context you will receive an error message).
  22. 1. To stop automating in the web view context and go back to automating the
  23. native portion of the app, simply call `context` again with the native
  24. context id to leave the web frame.
  25. ```javascript
  26. // javascript
  27. // assuming we have an initialized `driver` object for an app
  28. driver
  29. .contexts().then(function (contexts) { // get list of available views. Returns array: ["NATIVE_APP","WEBVIEW_1"]
  30. return driver.context(contexts[1]); // choose the webview context
  31. })
  32. // do some web testing
  33. .elementsByCss('.green_button').click()
  34. .context('NATIVE_APP') // leave webview context
  35. // do more native stuff here if we want
  36. .quit() // stop webdrivage
  37. ```
  38. ```java
  39. // java
  40. // assuming we have a set of capabilities
  41. driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
  42. Set<String> contextNames = driver.getContextHandles();
  43. for (String contextName : contextNames) {
  44. System.out.println(contextNames); //prints out something like NATIVE_APP \n WEBVIEW_1
  45. }
  46. driver.context(contextNames.toArray()[1]); // set context to WEBVIEW_1
  47. //do some web testing
  48. String myText = driver.findElement(By.cssSelector(".green_button")).click();
  49. driver.context("NATIVE_APP");
  50. // do more native testing if we want
  51. driver.quit();
  52. ```
  53. ```ruby
  54. # ruby
  55. # assuming we have a set of capabilities
  56. @driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => SERVER_URL)
  57. # I switch to the last context because its always the webview in our case, in other cases you may need to specify a context
  58. # View the appium logs while running @driver.contexts to figure out which context is the one you want and find the associated ID
  59. # Then switch to it using @driver.switch_to.context("WEBVIEW_6")
  60. Given(/^I switch to webview$/) do
  61. webview = @driver.contexts.last
  62. @driver.switch_to.context(webview)
  63. end
  64. Given(/^I switch out of webview$/) do
  65. @driver.switch_to.context(@driver.contexts.first)
  66. end
  67. # Now you can use CSS to select an element inside your webview
  68. And(/^I click a webview button $/) do
  69. @driver.find_element(:css, ".green_button").click
  70. end
  71. ```
  72. ```python
  73. # python
  74. # assuming we have an initialized `driver` object for an app
  75. # switch to webview
  76. webview = driver.contexts.last
  77. driver.switch_to.context(webview)
  78. # do some webby stuff
  79. driver.find_element(:css, ".green_button").click
  80. # switch back to native view
  81. driver.switch_to.context(driver.contexts.first)
  82. # do more native testing if we want
  83. driver.quit()
  84. ```
  85. ```php
  86. // php
  87. // assuming we have an initialized `driver` object in an AppiumTestCase
  88. public function testThings()
  89. {
  90. $expected_contexts = array(
  91. 0 => 'NATIVE_APP',
  92. 1 => 'WEBVIEW_1'
  93. );
  94. $contexts = $this->contexts();
  95. $this->assertEquals($expected_contexts, $contexts);
  96. $this->context($contexts[1]);
  97. $context = $this->context();
  98. $this->assertEquals('WEBVIEW_1', $context);
  99. // do webby stuff
  100. $this->context('NATIVE_APP');
  101. // do mobile stuff
  102. }
  103. ```
  104. ### Automating hybrid Android apps
  105. Appium comes with built-in hybrid support via Chromedriver. Appium also uses
  106. Selendroid under the hood for webview support on devices older than 4.4. (In
  107. that case, you'll want to specify `"automationName": "selendroid"` as a desired
  108. capability).
  109. Make sure
  110. [setWebContentsDebuggingEnabled](http://developer.android.com/reference/android/webkit/WebView.html#setWebContentsDebuggingEnabled(boolean)) is set to true as described in the [remote debugging docs](https://developer.chrome.com/devtools/docs/remote-debugging#configure-webview).
  111. Once you've set your desired capabilities and started an appium session, follow the generalized instructions above.
  112. ### Automating hybrid iOS apps
  113. To interact with a web view appium establishes a connection
  114. using a remote debugger. When executing against a
  115. simulator this connection is established directly as the simulator and
  116. the appium server are on the same machine.
  117. Once you've set your desired capabilities and started an appium session, follow the generalized instructions above.
  118. ### Execution against a real iOS device
  119. When executing against a real iOS device appium is unable to access the web view directly. Therefore the
  120. connection has to be established through the USB lead. To establish this
  121. connection we use the [ios-webkit-debugger-proxy](https://github.com/google/ios-webkit-debug-proxy).
  122. To install the latest tagged version of the ios-webkit-debug-proxy using
  123. brew, run the following commands in the terminal:
  124. ``` center
  125. # The first command is only required if you don't have brew installed.
  126. > ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"
  127. > brew update
  128. > brew install ios-webkit-debug-proxy
  129. ```
  130. You can also install the latest proxy by cloning it from git and installing
  131. it yourself:
  132. ``` center
  133. # Please be aware that this will install the proxy with the latest code (and not a tagged version).
  134. > git clone https://github.com/google/ios-webkit-debug-proxy.git
  135. > cd ios-webkit-debug-proxy
  136. > ./autogen.sh
  137. > ./configure
  138. > make
  139. > sudo make install
  140. ```
  141. If you use a recent device, you may need to install the latest
  142. ideviceinstaller, this is optional:
  143. ```
  144. brew install --HEAD ideviceinstaller
  145. ```
  146. Once installed you can start the proxy with the following command:
  147. ``` center
  148. # Change the udid to be the udid of the attached device and make sure to set the port to 27753
  149. # as that is the port the remote-debugger uses.
  150. > ios_webkit_debug_proxy -c 0e4b2f612b65e98c1d07d22ee08678130d345429:27753 -d
  151. ```
  152. You may also use the ios-webkit-debug-proxy-launcher to launch the
  153. proxy. It monitors the proxy log for errors, and relaunch the proxy
  154. where needed. This is also optional and may help with recent devices:
  155. ``` center
  156. # change the udid
  157. > ./bin/ios-webkit-debug-proxy-launcher.js -c 0e4b2f612b65e98c1d07d22ee08678130d345429:27753 -d
  158. ```
  159. **NOTE:** the proxy requires the **"web inspector"** to be turned on to
  160. allow a connection to be established. Turn it on by going to **settings >
  161. safari > advanced**. Please be aware that the web inspector was **added as
  162. part of iOS 6** and was not available previously.
  163. Now you can start an appium test session and follow the generalized instructions above.