How to delete specific table data from a table? - watir-webdriver

In my application I've a table with 40 rows. How do I delete some specific <td> named as "default", "tags", "city", "organic" in that table? All the deletes links are images with the same src name. Please find the attachment of the table row.
My step def:
Then(/^I click on all the delete rules on the setup page$/) do
words = ["default", "tags","organic","city"]
#current_page.delete_rules(:words => words)
end
In my ruby class I've added delete_rules method as below:
def delete_rules(words)
image_elements(:src => "/tracker/images/skin2/bin.png").click
end
Problem here is its deleting the first row in the table, not the rows which I've mentioned in the array.
My HTML is:
<tr>
<td>
tags
</td>
<td>
<a href="delete.page?did=83">
<img title="Delete" src="/tracker/images/skin2/bin.png">
</a>
<a href="edit.page?id=83">
<a href="activate.page?id=83">
</td>
<td>
</td>

you should use the following code in your delete method:
#check all <tr>
#browser.trs.each do |row|
# the row below will check the first <td> text in order to find "default", "tags", "city","organic"
if row.text.match(/default|tags|organic|city/)!= nil
# the row below will click the 1st link in the 2nd <td>
row.td(:index=>1).link.click
end
end

Related

How to find text for multiple elements using find_elements

I'm fairly new to using Selenium Remote Driver and Perl. What I'd like to do is to have Selenium find all elements on a page using a partial match of text. Then store the full text of those elements into an array.
I've tried using:
#elements = $driver->find_elements("//tbody/tr[td[2]/div/span[2][contains(text(),'matching text')]]")->get_text;
However, this doesn't seem to work.
I've also tried:
#elements = $driver->find_elements("//tbody/tr[td[2]/div/span[2][contains(text(),'matching text')]]");
This does populate the array with webelements.
my #elements;
my #elementtext;
my $elementtext;
#elements = $driver->find_elements("//tbody/tr[td[2]/div/span[2][contains(text(),'matching text')]]");
foreach my $currentelement (#elements) {
$elementtext = $driver->find_element($currentelement)->get_text();
push #elementtext, $elementtext;
}
This causes perl to generate an error because webdriver can't find the element. Any ideas on what I'm doing wrong and how to fix it? I suspect that the problem is with the contents of the #elements array not actually being xpath elements.
Here is an example of the html:
<td>
<div class='cellContent'>Atlanta</div>
</td>
<td>
<div class='cellContent'>City</div>
</td>
<td>
<div class='cellContent'>Georgia</div>
</td>
<td class='sort_column'>
<div class='cellContent'>USA</div>
</td>
</tr>
<tr>
<td>
<div class='cellContent'>Joe Passenger</div>
</td>
<td>
<div class='cellContent'> <span>NFL</span>
<span>matching text: Atlanta.Falcons.team</span>
</div>
</td>
I want to get 'matching text: Atlanta.Falcons.team' stored into the array.
you can directly point to span tag using this xpath.
//tbody/tr/td/div/span[contains(text(),'matching text')]

Accordion Bootstrap table with spacebars

I have seen questions pertaining to accordion but not entirely to my specific need. My table is populated using spacebars, more specific a nested each loop like this:
<tbody>
{{#each piece in pieces}}
<tr id="{{piece._id}}" class="itemList table-warning">
<th class="name tText">{{piece.name}} {{piece._id}}</th>
<td class="pdf tText" style="text-align: center"><a class ="pdf" href="{{piece.pdf}}" target="_blank"><i class="fa fa-file-text-o" aria-hidden="true"></i></a></td>
<td class="audio tText" style="text-align: center"><a class="audio" href="{{piece.audio}}" target="_blank"><i class="fa fa-volume-up" aria-hidden="true"></i></a></td>
<td class="format tText">{{piece.instrumentation}}</td>
<th class="price tText" >${{piece.price}}</th>
<td><input class ="qty" type ="number" name ="quantity" value="0" min="0"></td>
</tr>
<!-- Row that is being clicked-->
<tr class="partsList">
<td colspan="3"></td>
<th class="partName tText">{{piece.name}} Parts</th>
<td colspan="2"></td>
</tr>
{{#each part in piece.parts}}
<!-- Rows that should accordion -->
<!-- Currently ALL rows accordion on click. Need to accordion based on _id-->
<tr class="partList">
<td colspan="3"></td>
<td class="pname tText">{{piece.name}}: {{part.pname}}</td>
<td class="price tText">${{part.pprice}}</td>
<td><input class="qty" type="number" name="quantity" value="0" min="0"></td>
</tr>
{{/each}}
{{/each}}
</tbody>
I have a click function like so:
'click .partsList': function(e){
e.preventDefault();
$('.partList').nextUntil('tr.itemList').toggle();
}
The accordion function works, however it works with every instance of the each loop. i.e. every tr class ="partsList" will accordion at the same time on click.
To my understanding of the each loop, I can access the _id of a document using {{piece._id}}. If I set the table row id to equal that however, it only reads the _id of the FIRST document in the collection.
What I need is on click for the <tr class="partList"> to accordion based on _id. Or perhaps you would go about this a different way than bootstrap tables?
Please let me know if my question needs clarification.
You could filter the clicked .partslist using a data-* attribute. This causes jQuery to select only this specific items. Note that you need to attach the data-* attribute to the row that is clicked and to the rows that should collapse:
<tbody>
{{#each piece in pieces}}
...
<!-- Row that is being clicked-->
<!-- use the _id value of the piece context as data attribute -->
<tr class="partsList" data-id="{{piece._id}}">
<td colspan="3"></td>
<th class="partName tText">{{piece.name}} Parts</th>
<td colspan="2"></td>
</tr>
{{#each part in piece.parts}}
<!-- Rows that should accordion -->
<!-- Currently ALL rows accordion on click. Need to accordion based on _id-->
<!-- use the _id value of the piece context as data attribute -->
<tr class="partList" data-target="{{piece._id}}">
...
</tr>
{{/each}}
{{/each}}
</tbody>
'click .partsList': function(e, templateInstance){
e.preventDefault();
// get the data-id attribute of the clicked row
const targetId = templateInstance.$(e.currentTarget).data('id')
// skip if this row is not intended to toggle
if (!targetId) return
// toggle based on data-target attribute
templateInstance.$(`.partList[data-target="${targetId}"]`).nextUntil('tr.itemList').toggle();
}

Powermail: create fields from entries in database

My problem:
i need a matrix of fields in Powermail:
product_1 - price_1 - number_1
product_2 - price_2 - number_2
product_3 - price_3 - number_3
and so on. No problem to create this fields manually, but i need it derived from a database. The numbers of lines depends on the number of entries in the database.
is there a possibility to create fields "on the fly", perhaps by typoscript or a userfunc?
Thanks!
I would create a new field type an call it (e.g.) productsheet. In the manual there is an example how to do it: https://docs.typo3.org/typo3cms/extensions/powermail/ForDevelopers/AddNewFields/Index.html
Here two example page TSConfig lines for the new field:
# Add new fields
tx_powermail.flexForm.type.addFieldOptions.productsheet = Product Fields
tx_powermail.flexForm.type.addFieldOptions.productsheet.dataType = 1
Here is an example Productsheet.html partial file for this:
{namespace vh=In2code\Powermail\ViewHelpers}
<h2><vh:string.escapeLabels>{field.title}</vh:string.escapeLabels><f:if condition="{field.mandatory}"><span class="mandatory">*</span></f:if></h2>
<table>
<thead>
<tr>
<th scope="col">Menge</th>
<th scope="col">Artikel Nr.</th>
<th scope="col">Bezeichnung</th>
<th scope="col">Preis Fr./m</th>
</tr>
</thead>
<tbody>
<f:for each="{0:1,1:2,2:3,3:4,4:5,5:6,6:7,7:8,8:9,9:10}" as="key">
<tr>
<td>
<f:form.textfield type="number" class="mdl-textfield__input " name="field[{field.marker}][amount_{key}]" value="" />
</td>
<td>
<f:form.textfield class="mdl-textfield__input " name="field[{field.marker}][article_no_{key}]" value="" />
</td>
<td>
<f:form.textfield class="mdl-textfield__input " name="field[{field.marker}][description_{key}]" value="" />
</td>
<td>
<f:form.textfield class="mdl-textfield__input " name="field[{field.marker}][price_{key}]" value="" />
</td>
</tr>
</f:for>
</tbody>
</table>
Next step would be to insert fields - as you wrote - on the fly. So what about inserting an own viewhelper instead of defining a hardcoded array in the
Now you could prefill the fields with value="" by your own.
Hope that helps
You can use the TypoScript field of powermail to generate code from typoscript.
You can also use your own field type like discribed here with page TSConfig:
tx_powermail.flexForm.type.addFieldOptions.new = New Field
# The label could also be written with LLL: to localize the label
# Example to grab a value from locallang.xml or locallang.xlf
#tx_powermail.flexForm.type.addFieldOptions.new = LLL:EXT:ext/Resources/Private/Language/locallang.xlf:label
# Tell powermail that the new fieldtype will transmit anything else then a string (0:string, 1:array, 2:date, 3:file)
# Example for dataType array
#tx_powermail.flexForm.type.addFieldOptions.new.dataType = 1
# The new field is not just a "show some text" field. It's a field where the user can send values and powermail stores the values?
# You can tell powermail that this new field should be exportable in backend module and via CommandController
#tx_powermail.flexForm.type.addFieldOptions.new.export = 1
newis the field identifier. Powermail search by default for a partial with the identifier name e.g. New.html.
Now you can use a ViewHelper to get the data and create the html for the fields.

Selenium IDE Click on a button in a row identified by text

I am trying to get my script to click on a button called Enter Response located in the same row as a specific text (SID). I am able to locate both separately but can't seem to make both work at the same time.
The table is dynamic so I am using the SID, finding it's row and then want to click on it's response button. I.E. find text '123456' & click on 'Enter Response' found in the same row.
I tried this but am getting an error locator not found:
//tr/td/a[#class='title-abbr' and text()='123456']/following-sibling::td/a[text()='Enter Response']
Table Row Headers:
Title/Source/Source ID/SID/Create Date/(Enter Response button)/Form Type
<tr>
<td class="t-Report-cell" headers="TITLE_ABBR">this is my title</td>
<td class="t-Report-cell" headers="SOURCE_NAME">source1</td>
<td class="t-Report-cell" headers="SOURCE_NUMBER">142417</td>
<td style="background-color: rgb(13, 13, 13);" class="t-Report-cell" headers="SID_ABBR">
123456
</td>
<td class="t-Report-cell" headers="TRANSACTION_DATE">07/28/2016</td>
<td style="background-color: rgb(13, 13, 13);" class="t-Report-cell" headers="LINK" align="center">
<a style="background-color: rgb(0, 255, 255);" class="response-btn" href="f?p=58117:50:27077013481519::NO::P50_TRIGGER_ID:321860">Enter Response</a>
</td>
<td class="t-Report-cell" headers="FORM_TYPE">Questions</td>
</tr>
Any help would be greatly appreciated!
if I am looking right, you should first get to the parent node before trying to get to the next sibling....because "a" element has no sibling, so basically something like that:
//tr/td/a[#class='title-abbr' and text()='123456']/../following-sibling::td/a[text()='Enter Response']
You could also just use following-sibling::td[2] instead of selecting by text in the second part of xpath, but maybe you need it for some reason.
Btw some tips:
If the element could have multiple style classes, you will have to use contains
The same applies to text, beware of spaces etc. you should trim the text or use contains to avoid wrong selectors

Watir webdriver - How to click on dynamically generated last <td> in table?

In my application,I've to select the last td (which is an img) in table.Can anyone help me with this ?
HTML
<table>
<tbody>
<tr>
<td>
<td>
<a onclick="return confirm('Delete creative?')" href="delete.page?cid=47">
<a href="edit.page?id=47"><a href="?duplicateId=47">
<img title="Duplicate" src="/tracker/images/skin2/bolean.png">
</a>
</td>
</tr>
</tbody>
</table>
Implemenetd as below :
#browser.img(:src => "/tracker/images/skin2/bolean.png").click
#browser.img(:src => "/tracker/images/skin2/bolean.png").last.click
which is clicking on the first image.
When you do:
#browser.img(:src => "/tracker/images/skin2/bolean.png")
This returns the first matching element.
If you want to get all of the matching elements, you need to pluralize the method:
#browser.imgs(:src => "/tracker/images/skin2/bolean.png")
You will then get a collection of all images that have the specified src. You can then get the last one and click it similar to how Ċ½eljko did it for tds.
#browser.imgs(:src => "/tracker/images/skin2/bolean.png").last.click
Try this:
#browser.tds.last.click