Is there a best-practice for accessing cells programmatically via selectors?
I am trying to allow an e2e test easy access to the grid.
How are you rendering your Grid? Are you using react-test-renderer or direct DOM injection using something like ReactTestUtils.renderIntoDocument() or ReactDOM.render()? If the latter 2, what I have done in my tests is add a custom CSS class in each cell rendered with a pattern like this:
public static createCustomCellClass(rowIndex: number, columnIndex: number): string
{
return `pos-${rowIndex}-${columnIndex}`;
}
Then, if I want to get access the DOM element for a cell I can use a selector like "div.pos-12-13" to get the cell at rowIndex 12 and columnIndex 13.
That has worked well for me.
What I found is that because all cells are just s that are absolutely positioned, it is not straightforward to get at a specific cell.
Related
I would like to know how I could program in VBA using Selenium to click/choose on website the first autosuggestion, for example as you can see in the screenshot from amazon.es
Do you have any suggestions?
Tom
Since your situation is replicable I managed to test this two (2) approaches to your situation. I'll just remind you that is always good to show us some code you've tried in your question, so it does not feel like we are helping you from scratch, also try not to rely on images to show us your situation, unless is something that does not change much «like in this case, Amazon.es page». That reminded, let's go to the good part:
1) Advanced 1:
a. Spaces in class are change for dots (if there is any)
b. Requires to understand tag's meaning (a tag is like an object)
'Example
'Clicking first element under tag ("div" alone is a tag)
Selenium.FindElementByCss("div.autocomplete-results-container > div").Click
2) Advanced 2:
a. Requires to understand what ":nth-child" (CSS selector) is
'Example:
'Clicking first child of "div" (Everything inside "div" is a child - starts in 1)
Selenium.FindElementByCss("div.autocomplete-results-container > div:nth-child(1)").Click
I used Firefox to get the xPath property of that suggestion made by the web page. To quickly compare, I copied and pasted, one at a time, the xPath of the first 3 suggestions shown:
/html/body/div[1]/header/div/div[2]/div/div[2]/div[1]/div/div[1]/span[1]
/html/body/div[1]/header/div/div[2]/div/div[2]/div[2]/div/div[1]/span[1]
/html/body/div[1]/header/div/div[2]/div/div[2]/div[3]/div/div[1]/span[1]
So, for the first item, just use the first xPath. If you want to select, for example, the second, just vary the index of the sixth DIV, as we can see in the samples above. Assuming you already have part of the code that navigates to the page, use this, adapting the name of the WebDriver:
objSeleniumDriver.FindElementByXPath("/html/body/div[1]/header/div/div[2]/div/div[2]/div[1]/div/div[1]/span[1]"). click
I am trying to copy the text highlighted in Yellow (from the HTML image) using a Selenium VBA code with MS Excel to a string. However, it is crashing and not getting copied. But the same code is working if I were to use it on other websites where the division does not contain "Data-Role" element within a webpage. I tried to make use of all element type like ByName ById ByClass but none of these technique seems to be working. Please note I am using Selenium to access the Chrome browser. I am trying to store the Yellow highlighted text data into a string "Res". Any help or tip is much appreciated. Below is the sample code which I am trying to use.
Dim Res As String
Dim be As New WebDriver
On Error Resume Next
be.Start "chrome", ""
be.Get "the website from which I am tryig to pull data"
Res = be.FindElementByClass("text--1jzYQ uppercase--tL_HU").Text
[![enter image description here][2]][2]
Without having the website address (if able to test with it), or any error messages, can't tell you why it is crashing. Possibly accessing a dynamic element which is still resolving? Dunno.
However, those classes look dynamic, so in terms of robustness, perhaps try using a combination of more stable looking attribute = value css selectors:
be.FindElementByCss("[data-role=status-bar] [data-role=status-text]").text
In the following picture, the full xpath of the yellow highlighted bit of HTML is
/html/body/bx-site/ng-component/div/sp-sports-ui/div/main/div/section/main/sp-path-event/div/sp-next-events/div/div/div[2]/div1/sp-coupon1/sp-multi-markets/section/section/sp-outcomes/sp-two-way-vertical[2]/ul/li1/sp-outcome/button
I am using selenium to scrape some data from a website. The text of the xpath is what I want but I also need the class name of the yellow highlight bit of HTML. The class name constantly changes so I need a way to retrieve the class name along with the text. In this case the class name would be "bet-btn". I am using driver.find_element_by_xpath to get the text from the html, but can't figure out a way to retrieve the class name. Using the xpath is there a way in selenium to retrieve the class name of the yellow highlighted bit.
I would advise against using absolute xpath unless you really needed to
Try this instead:
elem = driver.find_element_by_xpath("//sp-outcome/button")
class_value = elem.get_attribute("class")
BTW that xpath is assuming there are no other //sp-outcome/button element paths on that page. If there are you would need to expand it some, but you still wouldn't need the entire absolute xpath. Those are generally pretty fragile.
I'm creating the Angular app which lets user save his html code (maybe it has style and script tag to control the view) and there is a live preview next to it. User can save the code and other users can come to see the code and the preview. I also worry about the security because of script tag and I want the script to work only with the code that user provides (Not allow to control or get the data in the parent frame). So I need some suggesting of how to do it.
I have tried the preview with iFrame by giving the value through the 'srcdoc' property, but it looks like the security is bad.
You would not need to use an iframe in that situation, you can just render an HTML string inside of a div element using the innerHtml input like so:
<div [innerHTML]="htmlString"></div>
Where htmlString is a string containing the HTML code. You will have to sanitize the content of that variable with the DomSanitizer.
constructor(private domSanitizer: DomSanitizer){}
...
ngOnInit() {
this.htmlString = this.domSanitizer.bypassSecurityTrustHtml(yourHTMLString);
}
I would like to add a target (e.g. _blank) property for a basicLeafNode on the Widget Container from the extension library.
I do not see the property for this.
Instead I could use the onClick property and return an URL. But then I still would have no target defined.
I could add a postScript method
var target = url;
view.postScript("window.open('"+target+"','_blank')")
but this fires when the container is loaded.
Can I add a target property without using the onClick Property?
In case I use the onClick property what method should I use or how I prevent the postscript is executed when the container is loaded?
The basicLeafNode doesn't currently provide a target property. You have 2 courses of action:
implement your own custom node as Michael suggested (hard)
use a class on the link e.g. "newpageopen" and add an onPageReady script that selects all a elements with the calss newpageopen and add the target property to the resulted HTML.
Something like this:
require(["dojo/ready","dojo/query"], function(ready){
ready(function(){
dojo.query("a.newpageopen").attr("target", "_blank");
});
});
Hope that helps;
To make this list of solutions a bit longer here another on wich does not require dojo or jquery:
Instead of using your code as SSJS like:
var target = url;
view.postScript("window.open('"+target+"','_blank')")
You can use the Client Side Code and add SSJS code in #{javascript:}' wich i think is the shortest solution on this Problem. Here a hardcoded example:
<xe:basicLeafNode>
<xe:this.onClick><![CDATA[window.open('#{javascript: return "http://www.google.com";}','_blank');]]></xe:this.onClick>
</xe:basicLeafNode>
the above example will also work with viewScope variables or SSJS funktions:
<xe:basicLeafNode>
<xe:this.onClick><![CDATA[window.open('#{javascript: return viewScope.url;}','_blank');]]></xe:this.onClick>
</xe:basicLeafNode>
You can add the target attribute using JavaScript. It's kind of inconvenient way but would work.
You can use dojo.query to query the HTML output generated by basicLeafNode on the Widget Container. Once you get the node of <a> then you can add attribute using dojo.attr.
One problem you might face is that the ID generated by XPages contains the character :, which will not work so you would have to escape it.
function escapeColon(controlID) {
return controlID.replace(/:/g, "\\3A");
}
So your code would be something like:
dojo.addOnLoad(function() {
dojo.attr(dojo.query(escapeColon("#{id:ID_of_basicLeafNode}") + " > a")[0], "target", "_blank");
});
The code escapeColon("#{id:ID_of_basicLeafNode}") + " > a" would generate a CSS selector. Here I am assuming that basicLeafNode on the Widget Container would generate something like this <div id="_id1:basicLeafNode"><a href=".... So the CSS selector would search for a tag with that ID and inside it the <a> tag. You would have to modify this based on the output that is generated.
As I said its a bit inconvenient. Also I haven't tested this code.