Select parent element of known element in Selenium - select
I have a certain element that I can select with Selenium 1.
Unfortunately I need to click the parent element to get the desired behaviour. The element I can easily locate has attribute unselectable, making it dead for clicking. How do I navigate upwards with XPath?
There are a couple of options there. The sample code is in Java, but a port to other languages should be straightforward.
Java:
WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
"return arguments[0].parentNode;", myElement);
XPath:
WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = myElement.findElement(By.xpath("./.."));
Obtaining the driver from the WebElement
Note: As you can see, for the JavaScript version you'll need the driver. If you don't have direct access to it, you can retrieve it from the WebElement using:
WebDriver driver = ((WrapsDriver) myElement).getWrappedDriver();
Little more about XPath axes
Lets say we have below HTML structure:
<div class="third_level_ancestor">
<nav class="second_level_ancestor">
<div class="parent">
<span>Child</span>
</div>
</nav>
</div>
//span/parent::* - returns any element which is direct parent.
In this case output is <div class="parent">
//span/parent::div[#class="parent"] - returns parent element only of exact node type and only if specified predicate is True.
Output: <div class="parent">
//span/ancestor::* - returns all ancestors (including parent).
Output: <div class="parent">, <nav class="second_level_ancestor">, <div class="third_level_ancestor">...
//span/ancestor-or-self::* - returns all ancestors and current element itself.
Output: <span>Child</span>, <div class="parent">, <nav class="second_level_ancestor">, <div class="third_level_ancestor">...
//span/ancestor::div[2] - returns second ancestor (starting from parent) of type div.
Output: <div class="third_level_ancestor">
Let's consider your DOM as
<a>
<!-- some other icons and texts -->
<span>Close</span>
</a>
Now that you need to select parent tag 'a' based on <span> text, then use
driver.findElement(By.xpath("//a[.//span[text()='Close']]"));
Explanation: Select the node based on its child node's value
Take a look at the possible XPath axes, you are probably looking for parent. Depending on how you are finding the first element, you could just adjust the xpath for that.
Alternatively you can try the double-dot syntax, .. which selects the parent of the current node.
This might be useful for someone else:
Using this sample html
<div class="ParentDiv">
<label for="label">labelName</label>
<input type="button" value="elementToSelect">
</div>
<div class="DontSelect">
<label for="animal">pig</label>
<input type="button" value="elementToSelect">
</div>
If for example, I want to select an element in the same section (e.g div) as a label, you can use this
//label[contains(., 'labelName')]/parent::*//input[#value='elementToSelect']
This just means, look for a label (it could anything like a, h2) called labelName. Navigate to the parent of that label (i.e. div class="ParentDiv"). Search within the descendants of that parent to find any child element with the value of elementToSelect. With this, it will not select the second elementToSelect with DontSelect div as parent.
The trick is that you can reduce search areas for an element by navigating to the parent first and then searching descendant of that parent for the element you need.
Other Syntax like following-sibling::h2 can also be used in some cases. This means the sibling following element h2. This will work for elements at the same level, having the same parent.
We can select the parent tag with the help of Selenium as follows:
driver.findElement(By.xpath("//table[#id='abc']//div/nobr[.='abc']/../.."));
this will help you to find the grandparent of the known Element. Just Remove one (/..) to find the immediate Parent Element.
Like:
driver.findElement(By.xpath("//table[#id='abc']//div/nobr[.='abc']/..));
There are some other ways to implement this, but it worked fine for me.
You can do this by using /parent::node() in the xpath. Simply append /parent::node() to the child elements xpath.
For example:
Let xpath of child element is childElementXpath.
Then xpath of its immediate ancestor would be childElementXpath/parent::node().
Xpath of its next ancestor would be childElementXpath/parent::node()/parent::node()
and so on..
Also, you can navigate to an ancestor of an element using
'childElementXpath/ancestor::*[#attr="attr_value"]'. This would be useful when you have a known child element which is unique but has a parent element which cannot be uniquely identified.
Have once way you don't need to execute script and you still get the parent element:
// identify element
WebElement ele =driver.findElement(By.xpath("//*[#id=\"ext-gen6\"]/div[5]/"));
//identify parent element with ./.. expression in xpath
WebElement parent = ele.findElement(By.xpath("./.."));
The key word here is xpath "./.."
Related
How do I pass data into a slotted element in Lit
How do I pass data to a slotted element in Lit? I’ve tried… <my-component> <slot .mydata=“${this.mydata}”> <\slot> <\my-component> But doesn’t seem to work, is programmatically the only way to do this?
We use slot on parent element. Default (unnmamed) slot <div class="parent> <slot></slot> </div> Named slot <div class="parent> <slot name="slot-name"></slot> </div> Then insert html tag inside parent by using slot. <main-parent> <div slot="slot-name"></div> </main-parent> For default slot,you don't need to add slot attribute. Note: Slot is used to insert external html inside parent element. If you don't need to insert html, you don't need to use slot. For pass data from parent to child. <next-child childattr=${this.mydata} ></next-child> For pass from child parent. You need to dispatch custom event with bubbles:true
Tinymce 4: how to allow only one element in the content with the defined class/attributes
Acutally I have two questions: Is there any way to configure tinymce to allow only one element in the content with a specific class/attribute? For example, I need only one <div class="title"></div> element in the content, so when you edit this element and press Enter, it creates another <div class="title"/>. Rather, I want just a div with a different class (i.e. <div class="text">). Is that possible? Is there any way to define allowed elements inside a div? For example, the only valid elements inside <div class="text"> are <br> and inline text. If you try to put a div/p/whatever inside, it will clean it out? Thanks!
1. forced_root_block : 'div', forced_root_block_attrs: { "class": "title"}, need to add a valid_element, valid_children and valid_class settings https://www.tinymce.com/docs/configure/content-filtering/#valid_elements https://www.tinymce.com/docs/configure/content-filtering/#valid_children https://www.tinymce.com/docs/configure/content-filtering/#valid_class
how to select following 2nd sibling in tritium?
I have a parent div with four children div. How do I select the second sibling when there is no class given? <div class="parent"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div>
$('//div[#class="parent"]/div[2]') This way second child can be selected directly
Proper format for Google Schema?
I've been experimenting with Google Schema and I've looked at a few code generators and they vary in design. The link I'm using for info for these examples: http://schema.org/Book 1) When is it proper to use itemscope itemtype="someSchemeURL.org" or an actual href? Example: <div itemprop="author" itemscope itemtype="http://schema.org/Person"> or <div itemprop="bookFormat" href="http://schema.org/bookFormatType"> The second example isn't even valid HTML since the href attribute isn't accepted on a div. 2) For the example above, is the first column always an itemprop and the second column always the itemscope itemtype? 3) If there is no itemscope itemtype specified, does the itemprop default to the parent itemscope itemtype? Example: <div itemscope itemtype="http://schema.org/Book"> <div class="book" itemprop="name"></div> <div itemprop="author" itemscope itemtype="http://shema.org/Person"> <div class="author" itemprop="name"></div> </div> </div> The .author class will result in the name attributed to "author" The .book class will result in the name attributed to "book" So this would mean that although multiple itemprop's have the same name, the itemprop always applies to the parent element, correct? 4) Where is it specified when to use meta, link, span, or div? Or is this left up to preference? Example: <div> <meta itemprop="datePublished" content="2013-07-01"> Some text </div> <div> Some text <link itemprop="bookFormat" href="http://schema.org/bookFormatType">Ebook </div> The second example is invalid, I know, but it's an example from one of the code generators. That specific generator produces invalid code so I know not to use it, but where are they getting their idea to use a link tag (albeit incorrectly)?
These docs can answer almost all of your questions. Maybe you've already seen them but just in case. Microdata Spec Getting Started Tutorial at Schema.org So answers for your questions in order they appear: 1.The first one is correct. The official microdata spec tells us Microdata is most useful, though, when it is used in contexts where other authors and readers are able to cooperate to make new uses of the markup. For this purpose, it is necessary to give each item a type, such as "http://example.com/person", or "http://example.org/cat", or "http://band.example.net/". Types are identified as URLs. The type for an item is given as the value of an itemtype attribute on the same element as the itemscope attribute. Example <section itemscope itemtype="http://example.org/animals#cat"> <h1 itemprop="name">Hedral</h1> <p itemprop="desc">Hedral is a male american domestic shorthair, with a fluffy black fur with white paws and belly.</p> <img itemprop="img" src="hedral.jpeg" alt="" title="Hedral, age 18 months"> </section> 2.No. Itemprop is used to indicate property of some entity. Itemscope - entity scope. And itemtype - type of the entity. These are different tags with different meaning which can be used separately (at least in theory). What doc says: At a high level, microdata consists of a group of name-value pairs. The groups are called items, and each name-value pair is a property. Items and properties are represented by regular elements. To create an item, the itemscope attribute is used. To add a property to an item, the itemprop attribute is used on one of the item's descendants. And examples <div itemscope> <p>My name is <span itemprop="name">Elizabeth</span>.</p> </div> <div itemscope> <p>My name is <span itemprop="name">Daniel</span>.</p> </div> 3.Even when itemscope itemtype are specified along with itemprop it is still property of the parent type. In this case this property is entity itself. And you're correct with your example: names will go to different entities. Here is what doc says about processing properties. The property value of a name-value pair added by an element with an itemprop attribute is as given for the first matching case in the following list: If the element also has an itemscope attribute The value is the item created by the element. If the element is a meta element The value is the value of the element's content attribute, if any, or the empty string if there is no such attribute. If the element is an audio, embed, iframe, img, source, track, or video element The value is the absolute URL that results from resolving the value of the element's src attribute relative to the element at the time the attribute is set, or the empty string if there is no such attribute or if resolving it results in an error. If the element is an a, area, or link element The value is the absolute URL that results from resolving the value of the element's href attribute relative to the element at the time the attribute is set, or the empty string if there is no such attribute or if resolving it results in an error. If the element is an object element The value is the absolute URL that results from resolving the value of the element's data attribute relative to the element at the time the attribute is set, or the empty string if there is no such attribute or if resolving it results in an error. If the element is a data element The value is the value of the element's value attribute, if it has one, or the empty string otherwise. If the element is a time element The value is the element's datetime value. Otherwise The value is the element's textContent. The URL property elements are the a, area, audio, embed, iframe, img, link, object, source, track, and video elements. 4.Left up to preference. There is general advice from search engines - markup consumers However, as a general rule, you should mark up only the content that is visible to people who visit the web page and not content in hidden div's or other hidden page elements. Schema.org doc gives good overview when usage of hidden elements may make sense. Many pages can be described using only the itemscope, itemtype, and itemprop attributes (described in section 1) along with the types and properties defined on schema.org (described in section 2). However, sometimes an item property is difficult for a machine to understand without additional disambiguation. This section describes how you can provide machine-understandable versions of information when marking up your pages. Dates, times, and durations: use the time tag with datetime Enumerations and canonical references: use the link tag with href Missing/implicit information: use the meta tag with content. Check this link for details.
Address elment by number from differnet parents using xpath
So I have this DOM structure <body> <div> <a></a> <a></a> </div> <div> <a></a> </div> </body> I can access two first link element by using xpath: //div/a[1] //div/a[2] And I want to access 3rd link by using same xpath structure (to enumerate them all) //div/a[3] But this method fails, because link elements have different parent div's Any way to correct my xpath to access all link elements by it's number?
You can use parenthesis: (//div/a)[3]