xpath working in chrome console but not in protractor script - google-chrome

html:
<div class="view doc">
<div class="view-doc-heading-dec mt10 ng-binding" id="docSummaryHeader"> Document Title </div>
<div class="view-doc-inner mt11 ng-binding" id="docBodyHeader">
</div>
I want to retrieve 'Document Title' in above elements with xpath:
$x('//*[#id=docSummaryHeader]')[0]
works in chrome console
but
element(by.xpath('//*[#id=docSummaryHeader]'))
in protractor doesn't allow [0]
If I use
element(by.xpath('//*[#id=docSummaryHeader]'))
it gives multiple elements in current html

Find all elements and get the desired one by index:
element.all(by.xpath('//*[#id="docSummaryHeader"]')).get(0);
or:
element.all(by.xpath('//*[#id="docSummaryHeader"]')).first();
Or, you can use the XPath-indexing (1-based):
element(by.xpath('//*[#id="docSummaryHeader"][1]'))

Actually you don't need xpath here:
$$('#docSummaryHeader').first();
Consider using CSS selector instead.

Related

Find xpath nearest element

I need to define an xpath before an element on the page. I have a string(FIO) that I can find using xpath and I need to bind to it. I don't understand how to do it.
My xpath witch i can find on page:
/html/body/div[1]/div[2]/section/div/div[1]/div/ul/li[2]//div[1]/span[contains(., '"+FIO+"')]
look at screenshot, i need find string 1, it have xpath:
/html/body/div[1]/div[2]/section/div/div[1]/div/ul/li[2]/ul/li[4]/ul/li[1]/div/div/a
image
string with my param(FIO) 2, have xpath:
/html/body/div[1]/div[2]/section/div/div[1]/div/ul/li[2]/ul/li[4]/ul/li[1]/div/div/div[1]/span
and i shortened it and inserted a variable:
/html/body/div[1]/div[2]/section/div/div[1]/div/ul/li[2]//div[1]/span[contains(., '"+FIO+"')]
how i can get xpath to element 2 with binding at element 1 ? maybe following sibling ?
sorry, i can't copy the code correctly, only like this:
</div>
</div>
<ul>
<li>
<div class="structure2__item1">
<div class="structure2__item2" style="">
<a class="structure2__position" href=https://**>
"String 2"
</a>
<div class="structure2__name" style="">
<span>String_FIO</span>
</div>
</div>
</div>
</li>
<li>
//div[child::span[contains(text(), "String_FIO")]]/preceding-sibling::a
This would help fetch the a tag from the span.
(From next time - please look out for the standards mentioned in the comments.)

How to use the exclude filter syntax in Xpath

I'm trying to parse a HTML from my firm by using Xpath, and here are the sample html structure of my target website:
<div class='my_target' id='A'>
This is a sample website HTML!
<span>APPLE</span>
<span>BANANA</span>
<span>ORANGE</span>
<span>IGNORE_1</span>
<span>IGNORE_2</span>
</div>
<div class='not_my_target' id='B'>
This is a sample website HTML!
<span>APPLE</span>
<span>BANANA</span>
<span>ORANGE</span>
<span>IGNORE_1</span>
<span>IGNORE_2</span>
</div>
And here are the elements I want to get:
<div class='my_target' id='A'>
This is a sample website HTML!
<span>APPLE</span>
<span>BANANA</span>
<span>ORANGE</span>
</div>
I've tried the code like:
//div[#id='A' and (not(self::span and contains(text(), "IGNORE_1")) or not(self::span and contains(text(), "IGNORE_2"))]
But it didn't work Q_Q
Did I write a wrong syntax ? Any one could help ?
Thanks 
Try this:
//div[#id='A']/span[not(contains(text(),'IGNORE_1')) and not(contains(text(),'IGNORE_2'))]
This will search for the ID value of A and then check span for not containing IGNORE_1 and IGNORE_2.
Problem with your case:
You are searching for ID and setting conditions that it shouldn't contain span, IGNORE_1 and IGNORE_2. That's why you are unable to get the desired result.
//div[#id='A' and (not(self::span and contains(text(), "IGNORE_1")) or not(self::span and contains(text(), "IGNORE_2"))]

Unable to find fitting selector using scrapy and xpath/css

I am currently experimenting with crawlers and how they work.
With that, I am currently stuck finding the right selector call for scrapy - neither xpath nor css works.
Here is the source code:
<body data-new-gr-c-s-check-loaded="14.980.0">
<div id="__next">
<div class="layout layout--public">
<section class="container-fluid container-section coach-list-section">
<div class="single-coach">
<div class="row">
<div class="col-md-4">...</div>
<div class="col-md-3 coach-main-content">
<div class="coach-info">...</div>
<h2>
Name, Age
</h2>
I want to retrieve the "Name, Age".
With the following code I only get an empty list back but I don't know why:
response.xpath('//body/div[contains(#id, "__next")]
/div[contains(#class, "layout layout--public")]
/section[contains(#class, "container-fluid container-section coach-list-section")]
/div[contains(#class, "single-coach")]').getall()
Note: the code is in one line, just for better visualization I entered it in multiple lines.
EDIT:
So I used the dev console in the browser and searched for the right xpath which is:
//body /div[contains(#id, "__next")] //div[contains(#class, "single-coach")] //div[contains(#class, "main-content")] /h2 /a
In the dev console, I can also see the right element highlighted.
Trying this xpath for scrapy doesn't work. I entered the following code in the scrapy shell...
response.xpath('//body/div[contains(#id,"__next")]//div[contains(#class,"single-coach")]//div[contains(#class,"main-content")]/h2/a').getall()
... and still received and empty list --> []
The ending .getall() should work as the xpath //body returns me the wished information.
SECOND EDIT
The content is loaded dynamically on the website. Hence, I was not able to find the right selector.
For everyone who also has this problem: I suggest to look it up in the scrapy documentation: https://docs.scrapy.org/en/latest/topics/dynamic-content.html
Try this:
response.xpath('//section//h2/a/text()').getall()

How can I add vue-select to JqxScheduler's dialog?

You can customize the JqxScheduler's edit dialog by appending the existing containers in the editDialogCreate method like this:
var titleSelector = $(`
<div>
<div class='jqx-scheduler-edit-dialog-label'>Előadás</div>
<div class="jqx-scheduler-edit-dialog-field">
<div><v-select :options="options"></v-select></div>
</div>
</div>`);
fields.subjectContainer.append(titleSelector);
I understand that this HTML inside won't be rendered in my Vue file, but I cannot add the rendered this rendered version by copy-paste as far as I know:
<div data-v-0a61aa6a="" dir="auto" class="v-select vs--single vs--searchable">
<div id="vs1__combobox" role="combobox" aria-expanded="false" aria-owns="vs1__listbox" aria-
label="Search for option" class="vs__dropdown-toggle"><div class="vs__selected-options">
...
</div>
</div>
My question is: How can I render this HTML and add it to the dialog?
I am using webpack and vue-router.
PS: I have read about the Vue.Compile method, but if I am correct, I cannot use it here.
You have several options:
Iclude this code into your html markup and put v-if directive on it, to hide/show it if necessary: v-if docs
Also you can try to create separate component for your title selector with Vue.component('component-title', {...}), docs

Cannot find correct element with same class name

I have the following HTML snippet:
<div id="result-1">
<div class="page">
<div class="collapsingblock">
<h4>Click Me</h4>
</div>
<div class="collapsingblock collapsed">
<h4>No, Click Me</h4>
</div>
</div>
</div>
What I'm trying to do, is to find the second collapsingblock and it's h4
I have the following:
(//div[#id="result-1"]/div[#class="page"]/div[#class="collapsingblock"])[2]/h4
My xPath doesn't return the element. If I replace it with [1] it finds the first instance of collapsingblock though
Any ideas?
Thanks
UPDATE:
I have just noticed, that the HTML is using JavaScript to add/remove an additional class to the second collapsingblock, which collapsed
The problem is that the value of the class attribute of the second inner div element is not equal to "collapsingblock", as you can see:
<div class="collapsingblock collapsed">
<h4>No, Click Me</h4>
</div>
Even though class has very clear-cut semantics in HTML, it does not mean anything special to XPath, it's an attribute like any other.
Use contains() to avoid this problem:
(//div[#id="result-1"]/div[#class="page"]/div[contains(#class,"collapsingblock")])[2]/h4
Then, the only result of the expression above is
<h4>No, Click Me</h4>
By the way, parentheses around the lefthand part of the expression are not necessary in this case:
//div[#id="result-1"]/div[#class="page"]/div[contains(#class,"collapsingblock")][2]/h4
will do exactly the same, given this particular input document.
the parenthesis is necessary because of priority :
(//div[#id="result-1"]/div[#class="page"]/div[#class="collapsingblock"])[2]/h4