I'm new to Selenium. I like to verify if a specific class contains a text snippet in JavaScript.
I have following HTML:
<div class="product-small">
<div class="data">
<p>This is some Text</p>
</div>
</div>
<div class="product-small">
<div class="data">
<p>This is some Text</p>
</div>
</div>
...
The above class are available multiple times on the page, so i have to iterate the "product-small" class to check if all 12 classes contains the text "some". If one of the 12 elements with that "product-small" class does not contain the text "some", the test will fail.
I thought something like this:
const cars = driver.findElements(By.className('product-small'));
cars.forEach(function (element) {
// Check if element contains "some" inside class "data"
// If element does not contain "some", test will fail
});
Thank you :)
A generic solution would be to collect the elements using the following xpath based Locator Strategy and probe the length, if it equals to 12 then mark it as Pass else mark it as Fail
const cars = driver.findElements(By.xpath("div[#class='product-small']//p[contains(., 'some')]"));
Related
i have a div that is displaying elements using v-for, like that
<div v-for"element in example" :id="element+'id'">
{{element}}
</div>
the elements have unique ids as you can see.
And everything is working but i have on specific moment when it needs to be styles differently.
When the current element contains ['some text'] in brackets like that i want to assign a style to this specific text, not the whole element only the text in brackets. Is there easy way for this, or?
Apply some styling if the ternary (? operator) returns true. Otherwise don't apply any styles at all.
<div v-for"element in example" :id="element+'id'" :style="element.includes('[some text]') ? 'custom-css-styles-here' : ''">
{{ element }}
</div>
you can pass your verification in a tenary operation
<div v-for"element in example" :id="element+'id'" :class="element.includes('[some text]') ? 'color-red' : 'color-blue'">
{{element}}
</div>
I don't really understand your verification but if you give me the release I can do the operation
I have an array of objects that have two fileds for example :
var array = [{type:"range", group:"group1"}, {type:"boolean", group:"group1"},
{type:"input", group:"group3"}... ]
Now in HTML by iterating through the array I want to create a div for every different GROUP and put the all elements with that group inside. But by putting I mean creating Inputs or Radiobuttons or Dropdowns depending on the TYPE of the element.
Now I have done this using AngularJS and mostly JS by appending objects to existing ones and so on. But I want to reduce as much as possible the usage of js because I am having issue with calling a function after the HTML is loaded (Call function after HTML is loaded AngularJS).
So I will be thankfull if someone give me an advice how this should look like mostly in html. I imagine something like this :
<div ng-repeat="object in array track by $index">
//if object.group div exists add to existing one (check maybe with js function ?)
// if object.type is ... add ...
// else if objec.type is ... add ...
...
//else object.group not exists create div with id object.group for example
// if object.type is ... add ...
// else if object.type is ... add ...
...
This should work for your case:
<div ng-repeat="(key, value) in array | groupBy: 'group'">
Group: {{key}}
<div ng-repeat="object in value">
<div ng-switch on="object.type">
<div ng-switch-when="range">Range block</div>
<div ng-switch-when="boolean">Boolean block</div>
<div ng-switch-when="input">Input block</div>
</div>
</div>
<br>
</div>
First looping groups elements, second will work with an elements in a group
I have a rather large list with todo items for which I want to add in place editing for:
[ ] first todo
[ ] second todo
[ ] third todo
after clicking on the second todo, the text of the second todo can be edited but you can also set some properties on the todo:
[ ] first todo
-----------------------------------------------------------
| [ ] second todo__________________ |
| due: __/__/____ |
| assigned: ______________ |
| |
| [save] [cancel] |
-----------------------------------------------------------
[ ] third todo
Now I can do something like:
<div ng-repeat="todo in todos">
<div ng-show="!doedit">
<input type="checkbox"> {{todo.title}}
</div>
<div ng-show="doedit" class="boxed">
<input type="checkbox"><input type="text" ng-model="todo.title"><br>
<input type="date" ng-model="todo.due"><br>
<input type="text" ng-model="todo.assigned"><br>
<button ng-click="doedit = false">save</button>
</div>
</div>
This should work (ignoring how the cancel button should work) but if I have a large todo list (100+ items) it will create a large amount of hidden elements which are probably never used but still bound to variables.
Is there a better way to do this? I looked at angular-xeditable which seems to dynamically add elements but it only works for simple input elements.
Or is having a large amount of hidden elements not an issue in angular?
ng-if removes the element from DOM entirely if it evaluates to false, including any watchers. For example:
<div ng-if="doEdit"></div>
This post explains some of the differences between ng-if and ng-show.
Having large amounts of hidden elements is not an issue only with the js but also with the DOM itself. you should not be doing that.
What can be done instead is
1. Using ng-if - keep a state of all the element lets say isEdited after the user clicks on the todo. Set the variable / state isEdited = !isEdited. This would set it to true if it is not already. Then inside your DOM write HTML using ng-if. Something like this
<div class="to-do-item"></div><br>
<div ng-if="isEdited">
<!--UI for the edited part-->
</div>
Since ng-if does not render the html till the condition is true. There wont be too much load on the DOM.
2. If the template for editing the to do item is same for all the todo items. You should prefer using ng-include with ng-if. This way the template would be downloaded the first time you try to edit the element. Then you can cache it so not network lag. Also there is no extra hidden html. Whatever needs to be on the page is on the page and is not hidden.
Wrapping all of that editing section into one container with an ng-if would reduce the number of internal watches down to one for the whole section when it wasn't active
I need to recursively read a hierarchic JSON object and build the HTML the same way as children objects will have to be inserted inside parents object.
Example:
<div class="level0">
<div class="children1 level1">
<div class="children1 level2">
.... N children
</div>
... N Children
</div>
</div>
... N Parents
Now, I'm building this with the following code:
function buildDivHtml(); // This generates all the parent/children code at that particular moment, meaning one by one.
object.find('selector of the row where the append goes').append('html from above function');
This causes browser to freeze. Is there a way to do this that works flawlessly without browser freezing?
In jQuery space denotes AND condition "," denotes OR condition, Is that right? But I am facing issues in that. Here is my sample html code
<td id="4">
<div id="test1" class="test1"></div>
<div id="test2" class="test2"></div>
</td>
<td id="5">
<div id="test1" class="test1"></div>
<div id="test2" class="test2"></div>
</td>
If I use the following query, it works
jQuery('#4 [id*=test1]')
it selects the correct div. However, if I use this query,
jQuery('#4 #test1')
it doesn't work. Any Idea?
It is not valid to have duplicate ids within the same document.
If you are building this dynamically then try prepending the parent id to the child so it would be like:
<td id="r4">
<div id="r4_test1" class="test1"></div>
<div id="r4_test2" class="test2"></div>
</td>
<td id="r5">
<div id="r5_test1" class="test1"></div>
<div id="r5_test2" class="test2"></div>
</td>
Note, starting an ID with a number is also invalid, so I took the liberty to prepend "r" to your row ids.
I would recommend using the selector:
$('#r5 .test1')
Space isn't strictly an 'and' condition.
In your own example, jQuery('#4 #test1') space means to get children of #4 called #test1 if you see what I mean
The jquery docs for this explain it better than I do!
jQuery('ancestor descendant')
Selects all elements that are descendants of a given ancestor.
Thinking of selectors in terms of "AND" and "OR" probably isn't the most helpful way to go about things. If a space actually meant "AND", then these two statements would be identical:
$('.parent_class .child_class')
$('.child_class .parent_class')
If a selector was a simple "AND", then these statements would select all items that meet both criteria.
In reality, these statements are very different. A space in jQuery and CSS selectors actually shows inheritance. When you have two separate classes, as in my example, you're always saying "select the class that is second in the list, only if it is contained by an element with the first class in the list."
You could say that a comma means "OR", but really it just separates two selecting statements from each other, so that you can select two completely separate items or groups of items.
The jQuery selector syntax borrows from CSS, so this group of tutorials on w3schools.com might be a helpful place to start.
I think you ought to drop the ids off the div tags and just work with classes.
use $('#d5 .test1') or
$('#d5').find('.test1')
I usually use the latter because it's just easier to read when I go back a month later to look at the code.
<td id="d4">
<div class="test1">w</div>
<div class="test2">x</div>
</td>
<td id="d5">
<div class="test1">y</div>
<div class="test2">z</div>
</td>