I'm using watir-webdriver have several lines of the same code shown below:
...
<p class="schedule-text">
by
MarketingClub
in
Marketing
</p>
I need to get the first links included in p tag and the second links included in p tag
so using page object I've added the following code:
links(:followees_category, :css => "#home-followees li.animate-in ul li[data-show-id] p.schedule-text a")
...
followees_category_elements.attribute("href")
the last row will give me both links : http://www.somesite2.com, http://www.somesite2.com
Unfortunately, I can't indicate in css :last/:first etc.
the second link can be gotten by changing css to :
#home-followees li.animate-in ul li[data-show-id] p.schedule-text a + a
but how can I get just the first links from such blocks?
Of course, I can get both links and work with every 2nd, but maybe there is an alternative solution?
You can use the css nth-of-type pseudo class to get elements based on their index (or relative position).
For example, a:nth-of-type(1) can be used to return all links that are the first line of their parent:
links(:followees_category, :css => "p.schedule-text a:nth-of-type(1)")
For the second links, you can do a:nth-of-type(2). Note that it is 1-based index.
links(:followees_category, :css => "p.schedule-text a:nth-of-type(2)")
For the first link, you can also do a:first-of-type:
links(:followees_category, :css => "p.schedule-text a:first-of-type")
If the second link is always the last link, you can also do a:last-of-type:
links(:followees_category, :css => "p.schedule-text a:last-of-type")
I would not recommend using css selectors like these, because they make your tests harder to read and more fragile.
But, whatever the selector is in the end, i would use Ruby's Enumerable methods to get the second links like this:
links.select.each_with_index {|_, i| i.odd? }
Related
In my case all identifiers in a page is generated dynamically. So I can't use xpath.
I've found method in the documentation: grabAttributeFrom.
How I can see what's inside, when I using cmd in --debug mode?
Can I use grabAttributeFrom for extracting xpath's from a page when I searching inputs?
How I can get access to inputs which have name and they xpath generates dynamically and I can't use xpath's?
I tried this code:
I.fillField(locate('input').inside('.jq-panel-body-default').at(2),'John');
but it doesn't work correct and generate exception:
FAIL Field "{"type":"xpath","output":null,"strict":true,"locator":{"xpath":".//input[ancestor::*[contains(concat(' ', normalize-space(./#class), ' '), ' jq-panel-body-default ')]][position()=2]"},"value":".//input[ancestor::*[contains(concat(' ', normalize-space(./#class), ' '), ' jq-panel-body-default ')]][position()=2]"}" was not found by text|CSS|XPath
How I can see what's inside, when I using cmd in --debug mode?
Inside.. what?
If you want to log value of attribute, grab it and log:
Scenario("test", async (I) => {
...
const attributeValue = await I.grabAttributeFrom(<locator>, <attribute>);
console.log(attributeValue);
...
});
Can I use grabAttributeFrom for extracting xpath's from a page when I searching inputs?
grabAttributeFrom is for grabbing of attributes value, not for xpath finding.
But if you ask, can you use xpath in locator argument, yes you can.
How I can get access to inputs which have name and they xpath generates dynamically and I can't use xpath's?
This is not enough to ask you. Share some DOM part or something to understand.
If you mean name attribute, you can use filtering by name: //input[#name="<your element name>"]
I'm trying to retrieve the value "CONGE STATUTAIRE" from the following html code
<span class="DescriptionLabel" id="lblProjectDescription">CONGE STATUTAIRE</span>
I've tried this
nom_proj = IE.Document.getElementsByClassName("DescriptionLabel")(0).innerText
The code pass this line without problem but the the value of nom_proj is " ", and I would have hope to get "CONGE STATUTAIRE" for result.
Could anyone tells me what's wrong with it? The rest of my code is working i.e. I can retrieve value by using the getelementbyID method.
Any help will be welcomed.
I would use the getElementById() method, to make sure it can return only one HTML element and not a collection of objects:
nom_proj = IE.Document.getElementById("lblProjectDescription").innerText
However, the reason why you get "" is most probably that the collection returned by getElementsByClassName() has more than one element (often, when retrieving object by class names).
Which means: in the Document of your browser there will be most probably more elements that are styled with the CSS class DescriptionLabel; for example, something like this:
<div name="emptyRow" class = "DescriptionLabel"></div>
You can test if there are more than one element by:
1) either, adding a watcher to IE.Document.getElementsByClassName("DescriptionLabel");
2) or, printing all the elements inside, I bet my hat you'll find inside more than one:
For Each obj In IE.Document.getElementsByClassName("DescriptionLabel")
Debug.Print obj.InnerText
Next obj
GENERAL SUGGESTION: if an HTML object has an id, use the getElementByID; that method returns a single object, not a collection, so even if you would be sure that the collection will contain a unique element, it would anyway be less clean and efficient in terms of coding.
I'm trying to mask the answer options that show up in a 3DGrid question item in Confirmit, using the value of a background variable.
E.g. when "background1" ==1, display answer category 1. If "background1" ==0, do not display answer category 1. If "background2" ==1, display category 3, otherwise do not. In any case, display answer category 2.
Hopefully this is easy for someone out there (I'm a psychologist, not a coder...so not so much so for me :/)
Thanks!
In order to access the data inside a question/variable we can use the f function of confirmit.
for instance:
f('my_question_id').get();
When masking a question, we need to pass in a Set object so Confirmit knows what Code's to show and not to show.
Often you will mask using a Set from a previous question. So you pass in the question_id and Confirmit does all the other magic.
Here we have the problem of not having a Set, so we will have to create our own.
For this, there are 2 approaches (can be found in the scripting manual under Working with Sets > Methods of the set Object > add and remove and Working with Sets > User defined functions...)
I'm going to stick to the first one because it is easier to use ;)
What we will do first is create a script node (it doesn't matter where you create it, just somewhere in the survey, I often have a folder Functions with all my script nodes in somewhere at the bottom of my survey)
In that script file we will have our function that crates our set:
function CreateMyAwesomeSet()
{
//create an empty Set
var mySet = new Set();
//if background1 equals 1, add 1 to our Set
if ( f('background1').get() == '1' )
{
mySet.add(1);
}
//return the Set of allowed Codes
return mySet;
}
Here we declare a function that we now can use wherever we want to.
So now, If we want to use this Set, we add a Code Mask to your grid:
CreateMyAwesomeSet()
You can ofcourse change the name of the function, and add extra if statements.
hope this helps
I'm following the code located at this page:
http://code.google.com/apis/ajax/playground/#localsearch_with_markers
the search the demo shows is:
// Execute an initial search
searchControl.execute('pizza');
How can I get it to search more than one term? For example something equivalent to:
// Execute an initial search
searchControl.execute('pizza');
searchControl.execute('coffee');
This method will only return the 'coffee' results. It completely ignores 'pizza'.
From reviewing this demo it appears to be possible...
http://code.google.com/apis/ajax/playground/#the_hello_world_of_local_search
if you look at the following code:
// Specify search quer(ies)
localSearch.execute('coffee New York NY');
and change it to:
// Specify search quer(ies)
localSearch.execute('pizza');
localSearch.execute('coffee');
It will return both pizza and coffe results. Any ideas to get this to show up on the map though?
I have an application written in groovy and I am having problems with the pagination of a resulting set.
I have a Controller called ReportingController. This controller has two methods called
listdoiTln and listdoiEv. Both methods are similar and at the end both have to render a list of reports. The last lines of both are as follows:
params.max = Math.min(params.max ? params.max.toInteger() : 15, 100)
render (view: 'list', model:[reportingInstanceList: reportingInstanceList, reportingInstanceTotal: i])
The list view is rendered as expected. At the footer of the list.gsp file I have:
<div class="paginateButtons">
<g:paginate controller="reporting" total="${reportingInstanceTotal}" max="25"/></div>
</div>
The list is working, the buttons for the pagination are there but it is always displayed the whole collection. Notice that I do not have files callled listdoiTln.gsp or listdoiEv.gsp. I am using list.gsp with different data models.
Surely I am doing something wrong.
Any hint?
Thanks in advance.
Luis
I had trouble with this, too, for quite a while. Try this:
Evaluate param.offset in the controller:
params.offset = params?.offset?.toInteger() ?: 0
Include the params in the model:
render (view: 'list',
model:[reportingInstanceList: reportingInstanceList,
reportingInstanceTotal: i,
params: params])
Check whether the value of reportingInstanceTotal is the value that you expect. That tripped me up for a while.
If it still doesn't work, let me know, or try looking at one of the list.gsp pages and its associated controller that are generated by the grails generate-all command.
The paginate buttons are quite cool, but there is little documentation and it takes longer than I expected to set them up.