Java Appium Driver Catch Elements When You Dont Know the Id

Appium plus curl

Did yous know that Appium is just a spider web server? That's right! I'm going to write a full edition at some point on the WebDriver Protocol, which is the API that Appium implements (and which, as you tin tell by the proper noun, was invented for the purpose of browser automation). Simply for at present, let's revel in the knowledge that Appium is just similar your backend spider web or API server at your company. In fact, you could host Appium on a server connected to the public internet, and give anybody the chance to run sessions on your devices! (Don't practice this, of course, unless you're a cloud Appium vendor).

Y'all may be used to writing Appium code in Java or another language, that looks similar this:

                          driver = new IOSDriver(new URL("http://localhost:4723/wd/hub"), capabilities); WebElement el = driver.findElement(locator); System.out.println(el.getText()); driver.quit();                                    

This looks like Java lawmaking, but what'south happening under the hood is that each of these commands is actually triggering an HTTP asking to the Appium server (that'southward why we need to specify the location of the Appium server on the network, in the IOSDriver constructor). We could take written all the aforementioned code, for instance, in Python:

                          driver = webdriver.Remote("http://localhost:4723/wd/hub", capabilities) el = driver.find_element(locator) print(el.text) commuter.quit()                      

In both of these cases, while the surface code looks dissimilar, the underlying HTTP requests sent to the Appium server (and the responses coming dorsum) are the same! This is what allows Appium (and Selenium, where we stole this compages from) to work in whatever programming linguistic communication. All someone needs to practise is code up a nice little client library for that linguistic communication, that converts that linguistic communication'south constructs to HTTP requests.

What all this ways is that we technically don't demand a client library at all. It's user-friendly to use 1, absolutely. But sometimes, we want to just run an advertizement-hoc command against the Appium server, and creating a whole new code file and trying to call back all the advisable syntax might exist too much work. In this case, we tin can just use curl, which is a command line tool used for constructing HTTP requests and showing HTTP responses. Roll works on whatever platform, so you can download it for your environment if it'southward non there already (it comes by default on Macs, for example). At that place are lots of options for using curl, and to apply it successfully on your own, you should empathize all the components of HTTP requests. But for at present, permit'southward have a await at how we might encode the previous four commands, without any Appium client at all, but by using curlicue!

                          # 0. Check the Appium server is online > curl http://localhost:4723/wd/hub/status  # response: {"value":{"build":{"version":"one.17.0"}},"sessionId":null,"status":0}                      

You lot can run into above that nosotros tin brand certain we have a connection to the Appium server just by running curl and and then the URL we want to retrieve, in this case the /status endpoint. We don't need any parameters to curl other than the URL, considering we're making a Go request, and so no other parameters are required. The output we become back is a JSON string representing Appium's build information. Now, allow's actually starting time a session:

                          # 1. Create a new session > curl -H 'Content-blazon: application/json' \        -X Mail \        http://localhost:4723/wd/hub/session \        -d '{"capabilities": {"alwaysMatch": {"platformName": "iOS", "platformVersion": "13.3", "browserName": "Safari", "deviceName": "iPhone eleven"}}}'  # response: {"value":{"capabilities":{"webStorageEnabled":imitation,"locationContextEnabled":false,"browserName":"Safari","platform":"MAC","javascriptEnabled":true,"databaseEnabled":faux,"takesScreenshot":truthful,"networkConnectionEnabled":faux,"platformName":"iOS","platformVersion":"thirteen.iii","deviceName":"iPhone 11","udid":"140472E9-8733-44FD-B8A1-CDCFF51BD071"},"sessionId":"ac3dbaf9-3b4e-43a2-9416-1a207cdf52da"}}  # save session id > export sid="ac3dbaf9-3b4e-43a2-9416-1a207cdf52da"                      

Let's break this one down line by line:

  1. Hither we invoke the scroll command, passing the -H flag in social club to set an HTTP request header. The header we set up is the Content-type header, with value application/json. This is so the Appium server knows we are sending a JSON string every bit the body of the asking. Why practise we need to send a body? Because we take to tell Appium what we want to automate (our "capabilities")!
  2. -10 POST tells curl we want to brand a POST asking. Nosotros're making a Mail service request because the WebDriver spec defines the new session creation control in a style which expects a POST request.
  3. We demand to include our URL, which in this case is the base URL of the Appium server, plus /session because that is the road defined for creating a new session.
  4. Finally, we need to include our capabilities. This is achieved by specifying a POST body with the -d flag. Then, we wrap up our capabilities as a JSON object inside of an alwaysMatch and a capabilities fundamental.

Running this command, I see my simulator popular up and a session launch with Safari. (Did the session go away earlier you accept time to practise anything else? And then brand sure you ready the newCommandTimeout capability to 0). We as well get a bunch of output similar in the block above. This is the result of the new session command. The thing I care most well-nigh here is the sessionId value of ac3dbaf9-3b4e-43a2-9416-1a207cdf52da, because I will need this to make future requests! Recollect that HTTP requests are stateless, so for united states of america to keep sending automation commands to the correct device, we need to include the session ID for subsequent commands, so that Appium knows where to direct each control. To save it, I tin just export information technology equally the $sid vanquish variable.

Now, allow'south notice an element! There's just 1 element in Appium's picayune Safari welcome page, so nosotros tin find information technology by its tag proper name:

                          # ii. Notice an element > curl -H 'Content-type: application/json' \        -X POST http://localhost:4723/wd/hub/session/$sid/element \        -d '{"using": "tag name", "value": "h1"}'  # response: {"value":{"element-6066-11e4-a52e-4f735466cecf":"5000","ELEMENT":"5000"}}  # save element id: > export eid="5000"                      

In the roll command higher up, we're making some other POST request, but this time to /wd/hub/session/$sid/element. Note the utilize of the $sid variable hither, then that we can target the running session. This road is the one we need to hit in gild to detect an chemical element. When finding an element with Appium, ii parameters are required: a locator strategy (in our case, "tag name") and a selector (in our case, "h1"). The API is designed such that the locator strategy parameter is called using and the selector parameter is called value, so that is what we have to include in the JSON torso.

The response we become back is itself a JSON object, whose value consists of two keys. The reason there are two keys hither is a scrap complicated, only what matters is that they each convey the same information, namely the ID of the chemical element which was just constitute by our search (5000). Just like we did with the session ID, we tin can store the element ID for use in time to come commands. Speaking of future commands, let's go the text of this chemical element!

                          # 3. Become text of an element > curl http://localhost:4723/wd/hub/session/$sid/chemical element/$eid/text  # response: {"value":"Let's browse!"}                      

This coil command is quite a fleck simpler, considering retrieving the text of an chemical element is a GET command to the endpoint /session/$sid/element/$eid/text, and nosotros don't demand whatever additional parameters. Notice how here we are using both the session ID and the chemical element ID, so that Appium knows which session and which chemical element we're referring to (because, again, we might have multiple sessions running, or multiple elements that we've establish in a particular session). The response value is the text of the element, which is exactly what we were hoping to detect! At present all that's left is to clean up our session:

                          # 4. Quit the session > curl -10 DELETE http://localhost:4723/wd/hub/session/$sid  # response: {"value":null}                      

This terminal control can use all the default curl arguments except we need to specify that we are making a DELETE request, since that is what the WebDriver protocol requires for ending a session. We make this asking to the endpoint /session/$sid, which includes our session ID so Appium knows which session to shut downwards.

That's it! I hope you've enjoyed learning how to achieve some "low level" HTTP-based control over your Appium (and Selenium) servers!

henleycoundtowned.blogspot.com

Source: https://www.headspin.io/blog/controlling-appium-via-raw-http-requests-with-curl

0 Response to "Java Appium Driver Catch Elements When You Dont Know the Id"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel