How to Select Choices input field having same class, type, Xpath everything is same - selenium

I have two input fields to enter choices which have same class, type. Id is different by it is dynamic and create on run time so i can't use id.I used indexing ,it's not working properly.
driver.findElement(By.xpath("//input[#type='text'][#placeholder='Provide a response entry that customers can select'][1]")).click();
driver.findElement(By.xpath("//input[#type='text'][#placeholder='Provide a response entry that customers can select'][1]")).sendKeys("Iphone 6");
driver.findElement(By.xpath("//input[#type='text'][#placeholder='Provide a response entry that customers can select'][2]")).click();
driver.findElement(By.xpath("//input[#type='text'][#placeholder='Provide a response entry that customers can select'][2]")).sendKeys("Iphone 7");
I used indexing in given image link.
click link to view code in organized way
Index 1 works in this case but unable to find index 2.
Given inspected html code is below of input field 1 and field 2
Field 1
Input field 1 image Xpath link
field 2
Input field 2 image link

If these two inputs are always in this sequence (so the first input is always first and second always second)
You can use:
driver.findElement(By.xpath("(//input[#type='text'][#placeholder='Provide a response entry that customers can select'])[1]")).click();
driver.findElement(By.xpath("(//input[#type='text'][#placeholder='Provide a response entry that customers can select'])[2]")).click();
At the same time I have corrected the syntax in indexing

Building on #Anand 's answer, you can simplify a little:
WebElement button1 = driver.findElement(By.xpath("(//input[#type='text' and #placeholder='Provide a response entry that customers can select'])[1]"));
WebElement button2 = driver.findElement(By.xpath("(//input[#type='text' and #placeholder='Provide a response entry that customers can select'])[2]"));
I think it's a little easier to read using and instead of stacking brackets.
I use it similarly for widgets:
WebElement header = driver.findElement(By.xpath("//div[contains(#class,'panel')]/div[contains(#class,'panel-heading') and text()[contains(.,'News Feed')]]"));

Related

Conditionally capturing pre-determined text in one field based on multiple choice selection in another field in REDCap

Problem: How can you capture a pre-determined or static text value based on what choice a user makes from a multiple choice menu on a survey?
Example: Suppose you have the following basic setup:
I have four text statements that correspond to options 1-4 (e.g., "Statement corresponding to Option 1", "Statement corresponding to Option 2", etc.). If the user chooses, say, Option 1 from the sample_options field, then I would like to capture the text value of the pre-prepared statement in the option_statement field. The user should not be able to alter the captured text statement (e.g., maybe hide the field using the #HIDDEN action tag).
Attempt: It seemed like this might be a problem that could be resolved with action tags, namely the #DEFAULT one, but I have been unable to do this. I also thought about trying to use a calculated field instead of a text field for option_statement, but calculated fields must return numeric values:
This seems like a problem that should be somewhat straightforward to tackle, but I have been baffled by just how hard it seems to be to simply capture static text in one field based on a user's selection in another field.
If I understand the question, you want to select a text string from a list of (in this case) 4 options, depending on the user selecting a choice from a radio/dropdown?
Probably the easiest method is to use #CALCTEXT (if you are on a sufficiently recent version), which allows you to conditionally populate a text field, i.e.:
#CALCTEXT(
if([sample_options] = 1, "This is the label for option 1",
if([sample_options] = 2, "This is the label for option 2",
if([sample_options] = 3, "This is the label for option 3",
if([sample_options] = 4, "This is the label for option 4", "This is an else value")
)
)
)
)
But if you do not have #CALCTEXT available to you, you can do this with a #DEFAULT, by constructing another radio field (#HIDDEN if you like) on a separate page or instrument (as #DEFAULT needs the value to exist in the database on page load, and so does not work dynamically on the page), with your four labels as the options with the same choice codes as your [sample_choices] field. For example:
1,This is the label for option 1
2,This is the label for option 2
3,This is the label for option 3
4,This is the label for option 4
And annotate it with:
#DEFAULT='[sample_choice]'
Thus if a user selects 3 for [sample_choice] and proceeds to the page or instrument that has the label field, the #DEFAULT tag will automatically select choice 3 from the label field, which can then be stored in the dataset and piped into an email, onto the page, or whatever.

XPath selector returns empty list

I'm trying to scrape data from store: https://www.tibia.com/charactertrade/?subtopic=currentcharactertrades&page=details&auctionid=12140&source=overview
There is no problem with getting data from 1st and 2nd table, but when I goes down, xpath returns only empty lists.
even tried to save response in file:
scrapy fetch --nolog "https://www.tibia.com/charactertrade/?subtopic=currentcharactertrades&page=details&auctionid=3475&source=overview" > response.html
for table with skills everything works good
sword = response.xpath('//div [#class="AuctionHeader"]/a/text()').get()
but when it comes to getting for example gold value, I get only empty list:
gold = response.xpath('/html/body/div[3]/div[1]/div[2]/div/div[2]/div/div[1]/div[2]/div[5]/div/div/div[3]/div[2]/div[2]/table/tbody/tr/td/div/table/tbody/tr[2]/td/div[2]/div/table/tbody/tr[3]/td/div/text()').get()
In chrome/firefox both selectors works smooth, but in scrapy only 1st one
I know there might be some problems with data updated by javascript, but it doesn't look like this case
Doesn't look like it's a javascript problem. Think you're not getting your XPATH selectors correct. It's best to be as specific as possible and not to use multiple nodes down. Here we can select the attribute TableContent to get the tables you want. There you can select each individual table that you require if needed.
Code Example
table = response.xpath('//table[#class="TableContent"]')[3]
gold_title = table.xpath('tr/td/span/text()')[2].get()
gold_value = table.xpath('tr/td/div/text()')[2].get()
output
'Gold: '
'31,030'
Explanation
Using the class attribute TableContent, you can select which table you want. Here I've selected the table with the gold values. I've then selected each row and the specific element which has the gold value. The values are hidden behind span and div elements. get() returns a string, getall() returns a list.

How to Identify Elements in Salesforce Lightning for Selenium

I am trying to automate Salesforce lightning using Selenium, but getting issues with identifying elements. Reason, its having dynamic IDs , and other attributes are either very long , or they are not unique.
For eg ,
<a id="170:1968;a" class="textUnderline outputLookupLink slds-truncate forceOutputLookup"
data-refid="recordId"
data-recordid="0059E000001aOCSQA2"
data-special-link="true"
href="#/sObject/0059E000001aOCSQA2/view"
target="_blank" rel="noreferrer"
title="" data-aura-rendered-by="170:1968;a" data-aura-class="forceOutputLookup"/>
In above code , ID is dynamic , Class is not unique, and all the Lookup elements are associated with it. Also the absolute path is not much trusted , and hence I am trying to find any concrete option to handle these elements. Any help will be highly appreciated.
Here, you could try using the contains method if at least a part of the id attribute value is static.
From your code, you could try
//a[contains(#id,"a")]/ //--extended xpath--
From the given html code, the 'a' in the id attribute of the a tag looks static, while the rest changes.
You can ask the developers to provide an id to the lightning component using aura:id
Then the dynamic id won't be generated.
You can try with field labels and fetch its parent node(s), and then fetching childs or brother nodes to locate related texts/text boxes etc.
Eg. You are in Account Edit/New page, and you want to fill in a value to the text box for Account Name field. So you can firstly try with //*[text()='Account Name']/parent::* to find an element that covers BOTH the field label and the text box.
And then you can check if the text box is a 'brother' or a 'child'. If it's a 'child' then try with //*[text()='Account Name']/parent::*(/parent::*)//*[attributes for the text box];
If it's 'brothers' then try with //*[text()='Account Name']/parent::*(/parent::*)/following-sibling::*[attributes for the text box]
You can use this logic to locate all type of fields in all standard lightning pages.

How do I pre-select rows in a DataTable based on the value in a column?

Situation:
I have a pandas dataframe which I convert into an html table via df.to_html(). I then add the DataTables class to the table. This DataTables-table has the following columns:
ID | X | Y | Val |...More columns...| Selection_Criteria |...More columns...
The values in Selection_Criteria can be either 1 or 0. I know that with:
$('#ProductList').DataTable( {
...
"fnInitComplete": function(oSettings, json) { $('#ProductList tbody tr:eq(0)').click(); }
});
(Source: http://code.datatables.net/forums/discussion/38171/automatic-select-of-the-first-row-on-reload)
..it is theoretically possible to select the first row. (In reality, I have not been able to simulate a click for the first row.)
But my question goes more towards: How do I automatically pre-select ALL rows where the value is 1 in Selection_Criteria? What is the best approach? Should this be done client/server side?
In pandas the term "select"(ing) means to screen out that which was not selected for. I know that in a table on a web page, selected can mean being highlighted to stand out from the others. There are a couple of ways you can do this on the server side. You could display two tables, one for each state of Selection_Criteria. This would save you the hassle of trying to select individual rows out of a table in the first place (which would be done with Javascript, not Pandas). While pandas has the ability to add a class to the resulting html, the class is applied to the element.
If you are using jquery you are going to use these pieces. as you haven't put example data I can't be exact.
replace x in the next line with the number of columns the Selection_Criteria=1 is across the table
$( "tr td:nth-child(x):contains('1')" ).addClass('selected');
There are solutions on the backend using beautifulsoup and css selectors, or lxml.etree with xpath selectors. But jquery is going to be the most concise with this problem.
#Aliester. Thank you for the pointer!
This helped me find the solution to my own question. What I did:
1.) Identify row index that I want to select when the table loads.
2.) Pass the index to js.
3.) Loop over the indices and apply the following command to each index entry:
table.row(':eq('+hit_index_row+')').select();
So I am using the API to select each individual row. This works for me and hopefully could be helpful to others as well. It may be a bit hacky, so more elegant suggestions are welcome!
You can do this by providing a function for the "rowCallback" option when initializing the DataTable. https://datatables.net/reference/option/rowCallback
Also it is generally better to use the API methods to select rows instead of just changing the class. I found that the DataTable + Select libraries keep an internal collection of selected row indexes (just current page if serverside processing is on) instead of using the class to resolve selected items.
So while the display will look right, if you just change the class, if you rely on any of the API methods to get selected items later on there will be issues. Additionally just changing the class on the row will not fire any of the "select" events on the table so you can't rely on those either.

Storing dynamic text in Selenium

I'm new to Selenium and had the following question about storing dynamic text...
In our web application, when a function is performed (i.e. transfer), a confirmation message is displayed (i.e. "function is completed. The reference number is #12345". The ref number is then displayed in a list with other ref numbers on another page. As part of my test, after the ref. number is generated, I would like to select from the list the ref number that was just generated.
Example
1 create item.
2 confirmation message displays
3 save ref number
4 navigate to other page which contains list of ref #s
5 select item from list that was just created (select using ref #)
Question: How do I save the ref number from the confirmation message so that I have Selenium select that number from the list of ref #'s?
Thanks,
D
Find out the identifier (CSS/XPath/etc.) of the UI element that displays the reference number, and then use the relatively getText() command. In Java,
String text = selenium.getText("your_identifier");