<div id = "board_code">
<div>
<span>r</span>
<span>o</span>
<span>w</span>
<span>1</span>
</div>
<div>
<span>r</span>
<span>o</span>
<span>w</span>
<span>2</span>
</div>
</div>
I am trying to get the string '2' to be used for comparison with char like { [ ( < ' "
I tried this:
alert($('#board_code > div').eq(1).eq(3).text();
output is: blank
When I tried this:
alert($('#board_code > div').eq(1).eq(0).text();
output is: row2
$("span").last().text()
That could work, but I'm not sure if it's good enough for your needs.
http://jsfiddle.net/6r2nP/1/
$("#board_code span").last().text()
That one might be better.
http://jsfiddle.net/6r2nP/2/
Related
I don't even know how to properly ask this.
I just started with python, and I'm trying to make a crawler.
Everything works fine but I can't "call" or "find" the second div with identical class names in the body.
I've been searching internet for help but the way people write their code is not similar to what I wrote.
so the HTML looks something like this:
<div class="card">
<div class="card-body">...</div>
<div class="card-body">...</div>
My code:
comp_link = comp_card.find('a', class_ = 'link')
href_link = comp_link['href']
link_final = 'https://www.someweb.com' + href_link
prof_text = requests.get(link_final).text
prof_soup = BeautifulSoup(prof_text, 'lxml')
comp_name = prof_soup.find('h2', class_ = 'company-name').text.strip()
comp_info = prof_soup.find('div', class_ ='col-md-12 col-lg-4')
but when I try to use
comp_info = comp_info.find('div', class_ = 'card-body'[1])
it doesn't work.
I've tried to experiment, use other peoples solutions from StackOverflow (but I'm too dumb).
Often, I prefer using CSS selectors. In this simple case you could select the second child that has the class name card-body. You can use the nth-child selector to grab the second div:
import bs4
html = """
<div class="card">
<div class="card-body">Not this</div>
<div class="card-body">But this</div>
</div>
"""
soup = bs4.BeautifulSoup(html)
print(soup.select('div.card-body:nth-child(2)'))
Output
[<div class="card-body">But this</div>]
If you happen to be in a situation where the targetted element is not actually the second element, but simply the second element with the class card-body, it may be advantagous to use nth-child(n of selector). This will select the second one element that matches the specified selector:
html = """
<div class="card">
<div class="other-class">Not this</div>
<div class="card-body">Or this</div>
<div class="card-body">But this</div>
</div>
"""
soup = bs4.BeautifulSoup(html)
print(soup.select('div:nth-child(2 of .card-body)'))
Output
[<div class="card-body">But this</div>]
BeautifulSoup's CSS selector logic is driven by the SoupSieve library, and more information can be found here: https://facelessuser.github.io/soupsieve/selectors/pseudo-classes/#:nth-child.
I'm trying to perform an action based on the results of an earlier assertion. I have the following situation, I want to determine the number of versions for a document, this is represented in the follwing html:
<ul data-testhook-id="accordion-body">
<li data-testhook-id="accordion-body-item">
<div>
<div data-testhook-id="version-1">
<div data-testhook-id="avatar">
<div data-id="tooltip">John Doe</div>
</div>
</div>
<span data-testhook-id="content">1. 17-08-2018 at 15:26</span>
</div>
<div data-testhook-id="version-2">
<div data-testhook-id="avatar">
<div data-id="tooltip">John Doe</div>
</div>
</div>
<span data-testhook-id="content">2. 20-08-2018 at 13:05</span>
</div>
<div data-testhook-id="version-3">
<div data-testhook-id="avatar">
<div data-id="tooltip">Jane Doe</div>
</div>
</div>
<span data-testhook-id="content">3. 20-08-2018 at 13:11</span>
</div>
<div data-testhook-id="version-4">
<div data-testhook-id="avatar">
<div data-id="tooltip">No Body</div>
</div>
</div>
<span data-testhook-id="content">4. 21-08-2018 at 13:11</span>
</div>
<svg width="12" height="12" data-testhook-id="icon-active-version"><path d="path-here"></path></svg>
</div>
</div>
</li>
Each element with test id data-testhook-id="version-xxx" is a line containing version information and its these div elements I want to count. for this I have set up the following:
cy.get('[data-testhook-id="accordion-body-item"] > div > div').its('length').as('versions')
Now if I add the following assertion, this passes without any problem
cy.get('#versions').should('equal', 4)
But if I try to use the outcome of the number of div's found as a variable in a console.log I no longer get '4' but [object, Object]. Tried this by:
var size = cy.get('[data-testhook-id="asset-versions"] [data-testhook-id="accordion-body-item"] > div > div').its('length')
console.log('foo ' + size)
Which results in foo [object Object] being printed to the console.
What I want to do is use the number of items in a selector to select an element, like:
cy.get('[data-testhook-id="accordion-body-item"] > div > div:nth-child(' + size + ')').find('svg').should('have.attr', 'data-testhook-id', 'icon-active-version')
But as the var is not a number I get the msg
Error: Syntax error, unrecognized expression: :nth-child
[data-testhook-id="asset-versions"] [data-testhook-id="accordion-body-item"] > div > div:nth-child([object Object])
Is it possible to use the number of elements found as a variable for a next selector?
Try this:
cy.get('[data-testhook-id="accordion-body-item"] > div > div').its('length').then((size) => {
cy.get('[data-testhook-id="accordion-body-item"] > div > div:nth-child(' + size + ')').find('svg').should('have.attr', 'data-testhook-id', 'icon-active-version')
});
You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously. What commands really return are Chainable<typeOfValueYouWant>, in another words, it's kind of queue object which resolves with desired value.
Read more here
BTW: I think you should consider change your approach for selecting elements. Read more here.
For those who are using Typescript - I wrote plugin for tslint which prevents making this mistake: https://github.com/krzysztof-grzybek/tslint-plugin-cypress
I am iterating through an array to show tables and also the rows in each of them.
It seems that all is good until the second iteration (so problem starts from the second table displayed), where the input's that I have in two td's don't show the data anymore, not the values I am passing nor the data-role: switch.
Example code:
<script type="text/x-kendo-template" id="some-id-table">
# for (var j = 0; j < firstArray.length; j++) { #
# var item = firstArray[j] #
<div>
<h3>#= item.info #</h3>
# if (item.details.length > 0) { #
<table id="item#=j#">
//....
<tbody>
# for (var i = 0; i < item.details.length; i++) { #
# var detail = item.details[i] #
<tr>
<td>#= detail.typeCode#</td>
<td>
<input
id="#=detail.id#"
type="number"
title=""
min="0"
onkeyup="X.something.viewModel.handleChangeAmount(event, #= j #, #= i #)"
onchange="X.something.viewModel.handleChangeAmount(event, #= j #, #= i #)"
data-idx="#= i #"
data-bind="value: item[#= j #].details[#= i #].amount,
readonly: item[#= j #].details[#= i #].transit,
disabled: item[#= j #].details[#= i #].transit,
attr:{class: item[#= j #].details[#= i #].confirmed ? 'boldTxt' : ''}"
/>
</td>
<td>
<input
id="#=detail.id#"
type="checkbox"
name="#=i#"
parentIdx="#= j #"
data-role="switch"
data-bind="checked: item[#= j#].details[#= i #].confirmed,
disabled: item[#= j#].details[#= i #].disableConfirm,
events: { change: onToggleConfirmChanged }"
>
</td>
<td>
<div
data-actionsheet-context="#= serializeContext(detail) #">
<span>#= detail.positionState #</span>
</div>
</td>
</tr>
# } #
</tbody>
</table>
# } else { #
<div> No item information found. </div>
# } #
</div>
# } #
(Tried to simplify code for clarity and there may be typos, but I hope you get the point about the input tags)
Extra note: in the data-bind property of the input tags I have tried as well to reference detail like so: value: detail.amount with no success, so I maybe the detail reference breaks somehow after the first iteration? (# var detail = item.details[i] #) The other 2 columns (first and last) are displayed correctly though.
Edit: To be more specific about what is wrong with the input tags, it's that the amount is not shown in the number input, and the second input is just a check box (without being correctly checked/unchecked) instead of being a switch.
Looking at the template for the first input, the html generated will look like this:
data-bind="value: item[0].details[0].amount,
However 'item' does not appear to be part of the model that the template is bound to. You create it within the template and can use it to drive logic and inject its value into the html with '#=item#' but you can't use it in a binding declaration. From the first line of the template, it appears that 'firstArray' is part of the model. Hence I suggest you want this html instead:
data-bind="value: firstArray[0].details[0].amount,
So try replacing 'item' with 'firstArray' in your data-bind. What I think is happening is that kendo starts binding the rendered template and is breaking somewhere internally because of the invalid data-bind string. The bind then stops and the rest of your html (the second iteration) doesn't get done. You may see some kendo errors if you check the console or have a debugger attached.
Using the following Protractor element and by.repeater() API methods below:
var targetRowText = 'Sales';
var targetGridName = 'myGrid';
var sel = 'grid-directive[grid-name="' + targetGridName + '"] .col-freeze .grid-wrapper';
var gridRows = element(by.css(sel).all(by.repeater('row in vm.sourceData.data'));
var result = gridRows.all(by.cssContainingText('span', targetRowText)).first();
I am able to select the following row element from a grid which I have labeled, myGrid:
<div id="rowId_21" ng-class-odd="'row-2'" ng-class-even="'row-3'" ng-class="vm.hideRow(row)" class="row-3 height-auto">
<div ng-repeat="column in vm.sourceData.columns" >
<div ng-if="!column.subCols" class="ng-scope">
<div ng-if="row[column.field].length !== 0" class="ng-scope highlight21">
<span ng-bind-html="row[column.field] | changeNegToPrenFormat" vm.highlightedrow="" class="ng-binding">
Sales
</span>
</div>
</div>
</div>
</div>
Please note that I have used by.cssContainingText() to look up the "Sales" span element.
MY PROBLEM:
That that I have located this row in var result, how can I retrieve the id attribute of that outer-most div ?
In other words, I need to selected <div id="rowId_21" so that I can reuse id="rowId_21" in a subsequent Protractor selector.
In jQuery, for example, I could use brute force to get that outer div id as follows :
var el = $('grid-directive[grid-name="Sales"] .col-freeze .grid-wrapper #rowId_21 span')
el.parentElement.parentElement.parentElement.parentElement;
Here's a high-level outlines of what I mean. The grid actually separates the left-most column from the actual data rows, so there are two distinct divs that accomplish this:
<div grid-directive grid-name="myGrid">
<div class="col-freeze" >
<!-- CONTAINS LEFT-MOST "CATEGORIES" COLUMN -->
</div>
<div class="min-width-grid-wrapper">
<!-- CONTAINS THE DATA ROWS-->
</div>
However, I'm struggling to do this in Protractor.
Advice is appreciated...
Bob
A straight-forward option would be to get to the desired parent element using the ancestor axis:
element(by.xpath("./ancestor::div[starts-with(#id, 'rowId')]")).getAttribute("id").then(function (parentId) {
// use parentId here
});
Though, I think that this going down and then up the tree should be considered as a sign that you are not approaching the problem in an easy and correct way.
I'm trying to select a control in order to manipulate it but I'm having a problem: I can't select it. Maybe it's because the xml structure, but I really can't change it because it is externally created. SO I have this:
<span class="xforms-value xforms-control xforms-input xforms-appearance xforms-optional xforms-enabled xforms-readonly xforms-valid " id="pName">
<span class="focus"> </span>
<label class="xforms-label" id="xsltforms-mainform-label-2_2_4_3_">Name:</label>
<span class="value">
<input readonly="" class="xforms-value" type="text">
</span>
<span class="xforms-required-icon">*</span>
<span class="xforms-alert">
<span class="xforms-alert-icon"> </span>
</span>
</span>
And what I need is to get the input (line 5). I tryed a lot, for example:
var elem01 = document.getElementById("pName");
console.log("getElementById: " + elem01);
var elem02 = document.evaluate(".//*[#id='pName']" ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );
console.log("evaluate: " + elem02);
console.log(elem02.singleNodeValue);
var elem03 = document.querySelector("#pName");
console.log("querySelector: " + elem03);
But none of that allows me to get a reference to the control. What's wrong?
With XPath, the problem seems to be the XML is no well formed, so document.getElementById("pName") doesnt return anything.
http://jsfiddle.net/wmzyqqja/7/
The problem with your example is that you are executing your Javascript before the relevant DOM elements are loaded (i.e. your code is in the head element):
This will fix the example:
window.onload = changeControlValue;
JSFiddle: http://jsfiddle.net/TrueBlueAussie/wmzyqqja/8/
Try this
var elem01 = document.getElementById("pName");
var inp = elem01.getElementsByTagName("input")[0];
(in JSFiddle the "onload" setting is required.)