Selenium IDE- Clicking on a dynamic id - html

I'm using the Selenium IDE and trying to get it to click on a specific search bar in a page, but the id of the search bar changes every time the page is refreshed. There are no other unique things I can use for contains().
<div class="ace_content" id="id-46319949-a1be-4d53-a2a8-fa644b37485b" style="margin-top: 0px; width: 764px; height: 60px; margin-left: 0px;">
This is the HTML. Is there any other way of finding the search bar?

As per the selenium docs, you have various selectors to choose from, other than id.
You can select on the class which appears to be static:
driver.find_elements_by_class_name('ace_content')
If multiple ace_content divs exist on the page, you can select the nth occurence of the div by just getting the n-1 index of the list returned by find_elements_by_class_name.

Resolved. I used this
//*[#class='ace_content']
to identify this xpath because ace_content was unique.

Related

Extract values from HTML when parent div contains a specific word (multi-nested divs)

I copy the HTML of a "multi-select" list from a page which looks like that:
and then paste the HTML version (after beautifying it online) in a notepad++ page.
I know want to use Regex in order to extract the lines that are enabled in that list. In other words, I want to see what options I had selected from that dropdown. There are many lines and it is impossible to scroll and find them all. So, the best way in my mind is to use that HTML and search for the divs that contain "enabled". Then, the inner divs should have the values that I am looking for.
The HTML is shown below:
<div class="ui-multiselect-option-row" data-value="1221221111">
<div class="ui-multiselect-checkbox-wrapper">
<div class="ui-multiselect-checkbox"></div>
</div>
<div class="ui-multiselect-option-row-text">(BASE) OneOneOne (4222512512)</div>
</div>
<div class="ui-multiselect-option-row ui-multiselect-option-row-selected" data-value="343333434334">
<div class="ui-multiselect-checkbox-wrapper">
<div class="ui-multiselect-checkbox"></div>
<div class="ui-multiselect-checkbox-selected">✔</div>
</div>
<div class="ui-multiselect-option-row-text">(BASE) TwoTwoTwo (5684641230)</div>
</div>
The outcome should return the following value only (based on the above):
(BASE) TwoTwoTwo (5684641230)
So far, I have tried using the following regex in notepad++:
<div class="ui-multiselect-option-row ui-multiselect-option-row-selected"(.*?)(?=<div class="ui-multiselect-option-row")
but it is impossible to mark all the lines at the same time and remove the unmarked ones. Notepad++ only marks the first line of the entire selection. So, I am thinking whether there is a better way - a more complex regex that can parse the value directly. So, in lines:
a) I either want to make the above work with another regex line in notepad++ (I am open to visualstudio if that makes it faster)
b) Or an easier way using the console in Chrome to parse the selected values. I would still like to see the regex solution but for Chrome console I have an
Update 1:
I used this line $('div.ui-multiselect-option-row-selected > div:nth-child(2)')
and all I need know, as I am not that familiar with the Chrome console export, is to get the innerHTML from the following lines:
Update 2:
for (var b in $('div.ui-multiselect-option-row-selected > div:nth-child(2)')){
console.log($('div.ui-multiselect-option-row-selected > div:nth-child(2)')[b].innerHTML);
which works and I now only have to export the outcome
}
Open up Chrome's Console tab and execute this:
$x('//div[contains(#class, "ui-multiselect-option-row-selected")]/div[#class="ui-multiselect-option-row-text"]/text()')
Here is how it should look using your limited HTML sample but duplicated.
If you have multiple multi-selects and no unique identifier then count which one you need to target (notice the [1]):
$x('//div[contains(#class, "ui-multiselect-option-row-selected")][1]/div[#class="ui-multiselect-option-row-text"]/text()')
All you have to do is use css selectors followed by a .map to get all the elements' innerHTML in a list
[...$('div.ui-multiselect-option-row-selected > div:nth-child(2)')].map(n => n.innerHTML)
The css selector is div.ui-multiselect-option-row-selected > div:nth-child(2) - which, as I've already mentioned in my comment, selects the 2nd immediate child of all divs with the ui-multiselect-option-row-selected class.
Then we just use some javascript to turn the result into a list and do a map to extract all the innerHTML. As you asked.
If the list is sufficiently big, you might consider storing the result of [...$('div.ui-multiselect-option-row-selected > div:nth-child(2)')].map(n => n.innerHTML) in a variable using
const e = [...$('div.ui-multiselect-option-row-selected > div:nth-child(2)')].map(n => n.innerHTML);
and then doing
copy(e);
This will copy the list into your clipboard, wherever you use ctrl + v now - you'll end up pasting the list.

How to select identically names div elements when writing cypress tests

I'm using cypress to create E2E test for our new application.
The application has a menu that contains buttons to display different data on a map screen. All of these buttons have the same div name, which I can differentiate between by entering the text name of the button:
cy.get('div.sb-item-body').contains('Historical Land Uses').click()
cy.get('div.sb-item-body').contains('Potentially Contaminative Industrial Uses (Past Land Use)').click()
cy.get('div.sb-item-body').contains('Potentially Infilled Land (Water)').click()
There is a further complication where two of the buttons have the same title (Landfill and Waste) as that dataset is in two different sections. So when I attempt to access the second -
cy.get('div.sb-item-body').contains('Landfill and Waste').click()
It is trying to select the first button with that name, and it's failing as that button has been collapsed and is no longer selectable.
Any help would be appreciated.
See the .eq() syntax.
You can use this when the selector returns multiple elements, e.g
cy.get('div.sb-item-body').contains('Landfill and Waste').eq(0).click()
cy.get('div.sb-item-body').contains('Landfill and Waste').eq(1).click()
I'm not sure if the 'collapsed' first button might interfere with it.
A more long-winded way is to use .then() to process the array of returned values, e.g
cy.get('div.sb-item-body').contains('Landfill and Waste').then(els => {
const buttons = [...els];
cy.wrap(buttons[0]).click()
expect(..).to...
cy.wrap(buttons[1]).click()
expect(..).to...
})
The spread operator converts the wrapped elements into an array you can work with, and cy.wrap() re-wraps the selected item making it clickable.

Once an item is selected, ui-select dropdown opens behind other fields

I'm using ui-select in an angularjs app that repeats for every row in a table (ng-repeat). This is the code for my ui-select.
<ui-select name="{{'selProperty' + $index}}" ng-model="thing.property"
theme="bootstrap" ng-required="true">
<ui-select-match placeholder="PLACEHOLDER TEXT">
{{$select.selected.displayName}}
</ui-select-match>
<ui-select-choices repeat="property in data.properties | filter: $select.search">
{{property.displayName}}
</ui-select-choices>
</ui-select>
I have a list of things on my $scope.data object, and the containing table uses an ng-repeat="thing in data.things". In each row of the table are fields that the user fills out to set properties on the thing. The dropdown lets the user assign an object property of the thing.
Everything works fine on first use. I get the list of properties and I can type in the partial search to filter the list. I select one, check the thing and see that it's property is correctly set. The problem is that when I re-open the dropdown list after having selected a value, the entire list shows up behind the other ui-select boxes on the other rows of the table. I tried it on a non-repeating page, and it showed up behind an <input type="text"></input> box as well.
I've tried adjusting the z-index to ridiculous numbers with no luck. I copied out the source HTML before and after selecting a value and compared, but there were no differences. I really don't understand why my list is showing up behind the other input elements on the page.
Please check the github Issue link below:
https://github.com/angular-ui/ui-select/issues/308
The solution is to add below CSS, See if it works for you.
.ui-select-choices {
position: fixed;
top: auto;
left: auto;
width: inherit;
}

Some part of my Django form should change based on TypedChoiceField list selection

I am new to Django. I have a requirement where in based on the TypedChoiceField list selection some part of the form should be changed. Meaning for a particular selection I need some fields to be displayed on the webpage and for other selection I need some other fields to be displayed on the webpage.
If there is already a similar page existing, please point me to that page, it will help me a lot.
What I would do is set up a javascript static file (here's a tutorial) that hides and shows elements using the select method.
For example, if you had categories that each needed a different set of fields, you could put all your categories into a <select> element and then using some simple JS, display the desired fields:
$("#select_object").change(function () {
toggleFields();
});
In that case, #select_object would be that <select> element. Whenever it changes (the user selects something) it shows the fields you want.

Selecting multiple CSS ids with only 1 number changing on each

I have an issue I am trying to select multiple CSS classes / ids.
The way my theme calls multiple buttons is it adds +1 to the button id like so:
edit-add-to-wishlist
edit-add-to-wishlist--1
edit-add-to-wishlist--2
edit-add-to-wishlist--3
etc
I wish to make said buttons all float to the right, without having to individually name and create each id in the CSS.
I have attempted to use the nth:child option as well as the * universal selector without much success.
Is selecting multiple a range (I guess you would call it) possible?
Something like this:
#edit-add-to-wishlist--* {
float: right;
}
You can use the attribute selector: [attr*=value]:
[id*=edit-add-to-wishlist] {
color: red;
}
jsFiddle here - it works
It selects all instances where a id contains edit-add-to-wishlist
[attr*=value]
Represents an element with an attribute name of attr and whose value contains at least one occurrence of string "value" as substring.
MDN documentation on the attribute selector
button[id^=edit-add-to-wishlist] {float:right}
Uses CSS3's substring matching by looking for <button id="edit-add-to-wishlist*> where the asterisk is a wildcard.