Looking for the best way to determine if an element is really empty.
<table id="foo">
<tr>
<td>Cell One</td>
<td></td>
</tr>
</table>
But both of these return true:
find("#foo td:nth-child(1)").should have_content('')
find("#foo td:nth-child(2)").should have_content('')
So I used this:
find("#foo td:nth-child(1)").text.should == 'Cell One'
find("#foo td:nth-child(2)").text.should == ''
Which seems to work, but doesn't check to see if the element may contain other elements. For example it may contain an image, link, or span.
I can check for each one of those individually(image, link, or span), but it seems like there should be better way.
Is there a way to test to see if the element is empty?
You can do the following to check that the element does not have any text and has no child elements (ie is actually empty):
# Has no child elements
find("#foo td:nth-child(2)").all('*').length.should == 0
# Has no text
find("#foo td:nth-child(2)").text.should==''
Related
I am trying to automate some scenarios using protractor where we need to verify whether the data is updating in dynamic table.
Please find below
HTML Code:
enter image description here
Table in page:
enter image description here
It can be done by verifying that element is present in the DOM with the added Group ID or Group Name.
For Group ID:
element(by.xpath("*//table//tbody//tr//td[1]//p[text()='Amanda Test
Group']")).isDisplayed()
For Group name:
element(by.xpath("*//table//tbody//tr//td[2]//p[text()='Amanda
Group']")).isDisplayed()
I'm assuming you're using Angular2+, yes?
In your HTML Template, you are probably using an *ngFor directive to populate the table dynamically. Add an index to the *ngFor (it's best practices for updating the DOM) in order to add a dynamic id to each element:
<tr *ngFor="let user of user; index as u" id="user-{{u + 1}}">
<td id="userName-{{u + 1}}">
{{user.firstName}} {{user.userName}}<br />
{{user.userName}}
</td>
<td id="userRoles-{{ u + 1 }}">
<span id="role-{{u + 1}}-{{ r + 1 }}" *ngFor="let role of user.roles; index as r">
{{ role.toUpperCase() + ', '}}
</span>
</td>
<!- Omitted code -->
</tr>
In your Page Object:
// Get first user on the table
get firstUser() {
return element(by.id('user-1');
}
// Get a specific user by id
public getUser(index: number) {
return element(by.id(`user-${index}`);
}
// Get all of the attributes for a single user by id
get userAttributes(index: number) {
return element.all(by.id(`user-${index}`);
}
I am not a fan of xpath selectors. Yes, they are faster. But in code that is dynamic or changes frequently, they are the most fragile of selectors. There is no reason your dynamic data cannot have a dynamic ID that clearly identifies each portion of the code you need.
Good luck!
here's the situation:
| ID | Name | ...
+----+--------+---
| 12 | Henry | ... a whole list of names, ids,&c ...you get the idea
+----+--------+---
| 13 | Julia | ...
+-------------+---
...
all the names are links. when selected, they load the rest of the table for editing by passing the name into a quick mysql query. but since i'm getting dupes, i need to grab the id as well to pass along. i also need it for updating the corrected (and correct!) record.
so, using MooTools, how do i grab the text from the neighbouring sibling when i click the link? hell, even just plain ol' JS will do.
here's the existing function:
function loadRecord(aName) {
console.log("loadRecord called with: "+aName);
user = $('submitterName').value;
id = $('table-id').text; // THIS IS THE PROBLEM RIGHT HERE. >_<
console.log('with user: '+user);
$('recordName').value = aName;
$('addRecordButton').value = 'Update Record';
$('addRecordData').action='_php/updateRecord.php'; // this isn't working either...
var action=$('addRecordData').action;
console.log(action);
checkUserDB(aName,user,id);
}
since there are multiple rows to the table, i can't assign a unique identifier to each ID to any benefit. i'm still stuck trying to pull the table-id's text that relates to the clicked link.
i hope i am clear. any help or illumination would be much appreciated.
TIA crew!
WR!
Here is the solution
HTML
<!--Change your HTML-->
<table>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
<tr>
<td>12</td>
<td><a>Henry</a></td>
</tr>
<tr>
<td>13</td>
<td><a>Julia</a></td>
</tr>
</table>
MooTools
window.addEvent('load', function(){
window.addEvent('click:relay(a)', function(event){//Add your selector inside relay
event.preventDefault();
console.log($(this).getParent('td').getPrevious().get('html'));
//Add Your AJAX code here
});
});
Here you are attaching a click event to anchor then selecting
parent(http://mootools.net/core/docs/1.5.2/Element/Element#Element:getParent)
then as you have ID in previous
element(http://mootools.net/core/docs/1.5.2/Element/Element#Element:getPrevious)
you can grab the previous element and get it's HTML
You can check the pen here http://codepen.io/arifmahmudrana/pen/yYQeJX
Please excuse if this is a very basic question, I'm learning. :(
I have this class:
class X {
def do_something {
db withSession {
val qresult = for {
(d, o) <- TABLE1 innerJoin TABLE2 on (_.TB1ID === _.TB2ID)
} yield(d, o)
}
}
}
and I would like to build a HTML table out of this, something like:
(record1) d.TB1ID d.F1VALUE d.F2VALUE o.F1VALUE o.F2VALUE o.TB2ID
(record2) d.TB1ID d.F1VALUE d.F2VALUE o.F1VALUE o.F2VALUE o.TB2ID
....
would anyone be kind enough to give me a pointer where to look? I've found plenty of examples but I have trouble connecting the qresult value to something I can bind in my template.
I am using Lift and Slick 1.0.1.
Assuming you have a table in your HTML template that looks like this:
<table>
<tr>
<td class="TB1ID"></td>
<td class="dF1VALUE"></td>
<td class="dF2VALUE"></td>
<td class="oF1VALUE"></td>
<td class="oF2VALUE"></td>
<td class="TB2ID"></td>
</tr>
</table>
Then, you should be able to have your CSS Transform look like:
"tr" #> qresult.map { case (d, o) =>
".TB1ID *" #> d.TB1ID &
".dF1VALUE *" #> d.F1VALUE &
".dF2VALUE *" #> d.F2VALUE &
".oF1VALUE *" #> o.F1VALUE &
".oF1VALUE *" #> o.F2VALUE &
".TB2ID *" #> o.TB2ID
}
That will key on the TR and repeat it for every row in your qresult list. Then, for each of the columns (represented above by their class attribute), it will output the value you want associated with it. Note that the * in the selector will append the value on the right as a child of the TD instead of replacing it with the value on the right.
You can find more information on CSS Selectors and outputting HTML here:
http://simply.liftweb.net/index-7.10.html
https://www.assembla.com/wiki/show/liftweb/binding_via_css_selectors
I have the below (simplified) code, which uses the following source:
<html>
<p>line 1</p>
<div>
<a>line 2</a>
</div>
</html>
soup = BeautifulSoup('<html><p>line 1</p><div><a>line 2</a></div></html>')
ele = soup.find('p').nextSibling
somehow_print_tag_of_ele_here
I want to get the tag of ele, in this case "div". However, I only seem to be able to get the tag of its children. Am I missing something simple? I thought that I could do ele.tag.name, but that is an exception since tag is None.
#Below correctly prints the div element "<div><a>line 2</a></div>"
print ele
#Below prints "None". Printing tag.name is an exception since tag is None
print ele.tag
#Below prints "a", the child of ele
allTags = ele.findAll(True)
for e in allTags:
print e.name
At this point, I am considering doing something along the way of getting the parent of ele, then getting the tags of parent's children and, having counted how many upper siblings ele has, counting down to the correct child tag. That seems ridiculous.
ele is already a tag, try doing this:
soup = BeautifulSoup('<html><p>line 1</p><div><a>line 2</a></div></html>')
print(soup.find('p').nextSibling.name)
so in your example it would be just
print(ele.name)
You can access anything inside an element as if accessing a dictionary.
Let's say you have an element like this one.
<input id="__VIEWSTATE3" name="__VIEWSTATE3" type="hidden" value="MwqzeTH4"/>
You can access each property like this
print(elem["id"])
# prints __VIEWSTATE3
print(soup.find('h1',id_='pdp_product_title'))
it doesnot print any detail please solved this
<h1 id="pdp_product_title" class="headline-2 css-zis9ta" data-test="product-title">Nike Air Force 1 Shadow</h1>
A page I have in my app will not display the required text so I checked my Apache error log and I found the following notice/error.
PHP Notice: Undefined index: PetManager_Model_Groomprocedures display.phtml on line 34
It is due to the fact that I'm trying to display a result from a query and it can't seem to obtain this item from my result array.
The situation is I'm querying a booking table that is related to a services table (theses elements display fine) the services table is in turn related to a procedures table(this is the element that will not display).
Can someone tell me where I'm going wrong i.e. my Query or my display code and how can I get this to work.
Query Code from my Display Action
if ($input->isValid()) {
$q = Doctrine_Query::create()
->from('PetManager_Model_Kennelbooking k')
->leftJoin('k.PetManager_Model_Kennelservices s')
->leftJoin('s.PetManager_Model_Groomprocedures g')
->leftJoin('k.PetManager_Model_Clients c')
->leftJoin('k.PetManager_Model_Kennels l')
->where('k.kennelbookingID = ?', $input->id);
if('k.groomingIncluded'==1)
{$q->addWhere('s.groomingGiven=g.groomProceduresID');
}
$result = $q->fetchArray();
if (count($result) == 1) {
$this -> view -> booking = $result[0];
The display code from my phtml file
<td class="key">Grooming Procedure </td>
</tr>
<tr>
<?php if($this->booking['PetManager_Model_Kennelservices']['groomingGiven']==NULL)
echo '<td>'.'There is no grooming procedure associated for this booking'.'</td>';
else echo '<td>'.$this->escape($this->booking['PetManager_Model_Groomprocedures']['groomprocedure']).'</td>';
;?>
</tr>
Many thanks in advance,
Graham
As you can see the index PetManager_Model_Groomprocedures is not defined in the booking-variable.
To see which keys are available do the following in your controller to get a debug output.
echo '<pre>';print_r($result[0]);echo '</pre>';exit;
You will see which keys are available in this array. I guess you are not selecting the wanted row explicitly. You will modify your query this way, that you also do select the wanted row.