For the W3C WebDriver "Find Element From Element" command, how does one format the element ID in request URL? - selenium

I'm learning how a WebDriver works, and I don't understand how to format the request URL for Find Element From Element.
The element ID of Find Element will return something like this:
{"element-6066-11e4-a52e-4f735466cecf": "e72b0320-5d61-4886-b903-5b2e4bb43d88"}
As I understand it, the above {key: value} format IS the element ID. If that is the case, how does one user that as the {element id} in "POST /session/{session id}/element/{element id}/element"? If {key: value} IS NOT the element ID, what is? And what would a properly formatted request URL look like?
Thanks!

In the above example, the element ID is "e72b0320-5d61-4886-b903-5b2e4bb43d88". It's a bit confusing because rather than creating an object that looks like this:
{"ELEMENT": "e72b0320-5d61-4886-b903-5b2e4bb43d88"}
We have the very odd:
{"element-6066-11e4-a52e-4f735466cecf": "e72b0320-5d61-4886-b903-5b2e4bb43d88"}
What's going on here? It has been deemed from on high that the key which in a JSON object indicates that we are dealing with an element ID is the arbitrary and constant string "element-6066-11e4-a52e-4f735466cecf". The reason is that any non-arbitrary key might end up being a return value of some unrelated JavaScript code. Consider this JavaScript code:
return document.getElementById('foo');
This could be used in ExecuteScript as follows (for example in Python):
driver.execute_script("return document.getElementById('foo');");
What should be returned here? Well we are dealing with an actual HTML element, which can't be converted into JSON and sent back over the wire to the Python client. So instead, WebDriver stores a reference to that element as an ID, and sends that back. But it can't just send back the ID as a string, because there's no way for driver.execute_script to know in advance what sort of thing might be returned. Maybe it's not an element ID--maybe it's some other string related to your application. In the past, the standard format for a JSON WebElement was as I noted above (with the ELEMENT key).
At some point, however, someone must have written some JavaScript code which resulted in a JS object which contained the word ELEMENT as key somewhere inside. This object had nothing to do with WebElements, but when it was returned via a call to driver.execute_script, the client converted it into a WebElement object!
Whether or not this scenario ever actually happened is beside the point; the point is that a simple short word like ELEMENT is ripe for name clashes. The spec authors wanted a way to unambiguously denote that we are dealing with a WebElement even if we encounter it in a serialized JSON format, and in a way that is not likely to clash with other things web developers or testers are doing.
So the most direct answer to your question is, your POST request should look like:
POST /session/{session id}/element/e72b0320-5d61-4886-b903-5b2e4bb43d88/element

Related

Camunda: Test whether JSON array contains an element

I would like a conditional flow to depend on whether a JSON attribute (containing a JSON array of strings) contains a specific element.
The following expression works if the element is present, but throws an exception if it is not:
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">
${ json_array.indexOf("foo")!=-1 }
</bpmn:conditionExpression>
The equivalent expression with lastIndexOf() also fails despite the documentation claiming that should not happen (issue 134).
Is there another way to do this?
This works, but seems rather clunky:
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">
${ json_array.toString().contains("\"foo\"") }
</bpmn:conditionExpression>
I hope there is a better way.

Simplexml get path from variable

Is there a way to pass the path to a simplexml node as a variable?
This is what I tried:
//set the path to the node in a variable
$comp = 'component->structuredBody->component';
echo count($xml->component->structuredBody->component); //=== 13
echo count($xml->$comp); //===0
echo count($xml->{$comp});//===0
What you need is XPath, and more specifically SimpleXML's xpath() method. Instead of traversing using PHP's -> operator, you would traverse using XPath's / operator, but otherwise, could achieve exactly the effect you wanted:
$comp = 'component[1]/structuredBody[1]/component';
echo count( $xml->xpath($comp) );
You might think that this could be simplified to 'component/structuredBody/component', but that would find all possible paths matching the expression - that is if there are multiple structuredBody elements, it will search all of them. That might actually be useful, but it is not equivalent to $xml->component->structuredBody->component, which is actually shorthand for $xml->component[0]->structuredBody[0]->component.
A few things to note:
Unlike most operations with SimpleXML, the result is an array, not another SimpleXML object (think of it as a set of search results). It is therefore vital that you check it is not empty before accessing element 0 as an object.
As you can see in the example above, XPath counts from 1, not 0. I don't know why, but it's caught me out before, so I thought I'd warn you.
The library SimpleXML is built on supports only XPath 1.0;
examples you see online for XPath 2.0 may not work.
XPath 1.0 has no notion of a "default namespace", and SimpleXML doesn't automatically register namespace prefixes for use in XPath, so if you're working with namespaces, you need to use registerXPathNamespace().

Proper error propagation in clojure

I'm currently working on my first major project in clojure and have run into a question regarding coding style and the most "clojure-esque" way of doing something. Basically I have a function I'm writing which takes in a data structure and a template that the function will try to massage the data structure into. The template structure will look something like this:
{
:key1 (:string (:opt :param))
:key2 (:int (:opt :param))
:key3 (:obj (:tpl :template-structure))
:key4 (:list (:tpl :template-structure))
}
Each key is an atom that will be searched for in the given data structure, and it's value will be attempted to be matched to the type given in the template structure. So it would look for :key1 and check that it's a string, for instance. The return value would be a map that has :key1 pointing to the value from the given data structure (the function could potentially change the value depending on the options given).
In the case of :obj it takes in another template structure, and recursively calls itself on that value and the template structure, and places the result from that in the return. However, if there's an error I want that error returned directly.
Similarly for lists I want it to basically do a map of the function again, except in the case of an error which I want returned directly.
My question is what is the best way to handle these errors? Some simple exception handling would be the easiest way, but I feel that it's not the most functional way. I could try and babysit the errors all the way up the chain with tons of if statements, but that also doesn't seem very sporting. Is there something simple I'm missing or is this just an ugly problem?
You might be interested in schematic, which does pretty similar stuff. You can see how it's used in the tests, and the implementation.
Basically I defined an error function, which returns nil for correctly-formatted data, or a string describing the error. Doing it with exceptions instead would make the plumbing easier, but would make it harder to get the detailed error messages like "[person: [first_name: expected string, got integer]]".

dojo.place how to pass parameter without surrounding HTML?

I'd like to do something like this:
dojo.place(this.message.subject, this.apSubject);
But it throw exception in Dojo 1.7 (I'm completely new to Dojo so I don't know if the same problem is under older versions)
To get it work I did:
dojo.place('<span>' + this.message.subject + '</span>', this.apSubject);
It looks like Dojo parse the first parameter of dojo.place and if there is no HTML it throw exception.
How to use it without spans?
Check the docs, In particular, the description of what the first argument receives:
dojo.place(node, refNode, pos)
node
Can be a String or a DOM node. If it is a string starting with “<”, it is assumed to be an HTML fragment, which will be created. Otherwise it is assumed to be an id of a DOM node.
Therefore, one things you can do is create a text node with the text you want
dojo.place( document.createTextNode(this.message.subject), this.apSubject)
And another thing you could try would be setting the innerHTML instead of using dojo.place:
this.apSubject.innerHTML = this.message.subject;
BTW, In my humble opinion, dojo.place is normaly kind of annoying to use. However, since I am not often doing this kind of DOM manipulation, I don't really know what are the alternatives people prefer to use.

Is it meaningful to verifyText() on an element that has just had type() executed on it?

I'm curious about whether the following functional test is possible. I'm working with PHPUnit_Extensions_SeleniumTestCase with Selenium-RC here, but the principle (I think) should apply everywhere.
Suppose I execute the following command on a particular div:
function testInput() {
$locator = $this->get_magic_locator(); // for the sake of abstraction
$this->type( $locator, "Beatles" ); // Selenium API call
$this->verifyText( $locator, "Beatles" ); // Selenium API call
}
Conceptually, I feel that this test should work. I'm entering data into a particular field, and I simply want to verify that the text now exists as entered.
However, the results of my test (the verifyText assertion fails) suggest that the content of the $locator element are empty, even after input.
There was 1 failure:
1) test::testInput
Failed asserting that <string:> matches PCRE pattern "/Beatles/".`
Has anyone else tried anything like this? Should it work? Am I making a simple mistake?
You should use verifyValue(locator,texttoverify) rather than verifyText(locator,value) for validating the textbox values
To answer your initial question ("Is it meaningful ..."), well, maybe. What you're testing at that point is the browser's ability to respond to keystrokes, which would be sort of lame. Unless you've got some JavaScript code wired to some of the field's properties, in which case it might be sort of important.
Standard programmer's answer - "It depends".