i have list items. how to read them all by selenium - selenium

<div class="validation-summary-errors" data-valmsg-summary="true">
<ul>
<li>Service User Number must be 6 characters</li>
<li>PSL ID is required</li>
<li>>Bank Account Id (was Credit AccID) is required</li>
<li>Account Name is required</li>
<li>Sort Code is required</li>
<li>Account Number is required</li>
<li>Bank Statement Narrative is required</li>
<li>Company Name is required</li>
<li>Contact Name is required</li>
<li>Email Address is required</li>
<li>Customer Services Phone Number is required</li>
<li>Phone Number is required</li>
<li>Address is required</li>
<li>Reference Number Prefix is required</li>
<li>Report Email Address is required</li>
</ul>
</div>
i want to read all the list and get their values of it. is someone help me as quick as possible. as selenium doesnt recognize unordered tag as it doesnt have name and id anything.....please help..

You can do this like this:
public void test() {
WebElement ul = driver.findElement(By.cssSelector("div.validation-summary-errors ul"));
List<WebElement> lis = ul.findElements(By.tagName("li"));
for (WebElement li : lis) {
// do something with li.getText();
}
}

Why do it in two steps? We can find the li in one selector;
public void test() {
WebElement lis = driver.findElement(By.cssSelector("div.validation-summary-errors ul>li"));
for (WebElement li : lis) {
// do something with li.getText();
}
}

#sircapsalot's answer is good, but I would change the first CSS selector to address OP's requirement "selenium doesnt recognize unordered tag as it doesnt have name and id anything"
public void test() {
WebElement ul = driver.findElement(By.cssSelector("div.validation-summary-errors ul"));
List<WebElement> lis = ul.findElements(By.tagName("li"));
for (WebElement li : lis) {
// do something with li.getText();
}
}

If your SVG data looks like this :
<div id="content-data" class="col-md-12" style="height:666px;">
<svg id="pie-draw-488172" width="492" height="616"><g transform="translate(226,318)">
<text id="pie-text" cursor="default" y="-226" x="241">Compute (227,311)</text>
<text id="pie-text" cursor="default" y="-211" x="241">Database (98,005)</text>
<text id="pie-text" cursor="default" y="-196" x="241">Storage&Content Delivery (69,436)</text>
<text id="pie-text" cursor="default" y="-181" x="241">Networking (30,874)</text>
<text id="pie-text" cursor="default" y="-166" x="241">Other (11,273)</text>
</svg></div>
then use this
public List<IWebElement> content_data = new List<IWebElement>();
content_data = driver.FindElement(By.Id("content-data")).FindElements(By.TagName("text")).ToList();

Related

How do I setup Birthdates using Yii3 and its Cycle-ORM integration?

Preconditions
mySql database client_birthdate field set as DATE and nullable if user does not enter date.
User inputs Client's Birthdate on __form textbox as a string in mySql format YYYY/MM/DD or not.
Yii3's ClientForm gets the string or empty string and converts to DATETIME so that Cycle Orm can process it.
Yii3's ClientService saves the date using Cycle's Client Entity's getter and setter methods and annotations.
Php 7.4.9
Typed property. Previously php allowed this variable declaration below a class public $var; now inserting typed property between public and $var ie public ?string $var = '' excludes other types. Question mark before type allows for null value input. So only two alternatives.
Understanding mySql's '0000-00-00' for non date input.
Download fork of https://github.com/yiisoft/yii-demo
dateHelper.php (adapted from Invoiceplane)
/**
* #return string|null
*/
public function date_from_mysql($date, $s)
{
//if previous input was not a date mySql would have input '0000-00-00'
if ($date <> '0000-00-00') {
//CYCLE converts all dates to DateTimeImmutable
$date = DateTime::createFromImmutable($date);
//$date = DateTime::createFromFormat('Y-m-d', $date);
//eg. $date->format('Ymd')
return $date->format($s->setting('date_format'));
}
return $date;
}
return '';
}
__form.php caption
<div class="mb-3 form-group has-feedback">
<label form-label for="client_birthdate"><?= $s->trans('birthdate'); ?></label>
<?php
$bdate = $body['client_birthdate'] ?? null;
if ($bdate && $bdate != "0000-00-00") {
//use the DateHelper
$datehelper = new DateHelper();
$bdate = $datehelper->date_from_mysql($bdate, false, $s);
} else {
$bdate = null;
}
?>
<div class="input-group">
<input type="text" name="client_birthdate" id="client_birthdate" placeholder="1900/12/01"
class="form-control data-datepicker"
value="<?= Html::encode($bdate); ?>">
<span class="input-group-addon">
<i class="fa fa-calendar fa-fw"></i>
</span>
</div>
</div>
Entity/Client.php
declare(strict_types=1);
namespace App\Invoice\Entity;
use \DateTime;
/**
* #Entity(
* repository="App\Invoice\Client\ClientRepository",
* mapper="App\Invoice\Client\ClientMapper",
* constrain="App\Invoice\Client\Scope\activeScope"
* )
* #Table(
* indexes={
* #Index(columns={"client_active"}),
* }
* )
*/
class Client
{
/**
* #Column(type="date", nullable=true)
*/
private $client_birthdate = '';
//CYCLE converts all date formats ie. DATE, DATETIME, to DateTimeImmutable so
work with DateTimeImmutable
public function __construct($client_birthdate = '')
public function getClient_birthdate() : ?DateTimeImmutable
{
if (isset($this->client_birthdate) && !empty($this->client_birthdate)){
return $this->client_birthdate;
}
if (empty($this->client_birthdate)){
return $this->client_birthdate = null;
}
}
public function setClient_birthdate(?\DateTime $client_birthdate): void
{
$this->client_birthdate = $client_birthdate;
}
Client/ClientForm.php
declare(strict_types=1);
namespace App\Invoice\Client;
use Yiisoft\Form\FormModel;
use Yiisoft\Validator\Rule\Required;
use \DateTimeImmutable;
use \DateTime;
final class ClientForm extends FormModel {
private ?string $client_birthdate = null;
public function getClient_birthdate(): ?\DateTime
{
if (isset($this->client_birthdate) && !empty($this->client_birthdate)){
return new DateTime($this->client_birthdate);
}
if (empty($this->client_birthdate)){
return $this->client_birthdate = null;
}
}
Client/ClientService
<?php
declare(strict_types=1);
namespace App\Invoice\Client;
use App\Invoice\Entity\Client;
use App\User\User;
final class ClientService
{
private ClientRepository $repository;
public function __construct(ClientRepository $repository)
{
$this->repository = $repository;;
}
public function saveClient(User $user, Client $model, ClientForm $form): void
{
$model->setClient_birthdate($form->getClient_birthdate());
Things to look out for:
Ensure _form 'id' and 'name' values eg. client_birthdate correspond to Entity #column and Database tables fields. ie Use field names consistently
through Entity, Annotations. The ClientForm's getter method will receive data from the __form which is a string or null. The getter will convert this to a DATETIME or null so that CYCLE ORM (Spiral Framework) can process it.
Ensure initialization in Entity/Client.php instantiation area ie. BEFORE construct and IN construct.
Tips
Annotations above function are read by Cycle's annotations.
use \DateTime; before Annotations. Don't forget backslash to indicate DateTime is a php class not in current Namespace.
mySql type DATE in database and 'date' included in annotation below. ie. * #Column(type="date", nullable=true) otherwise Cycle will not be able to read it.
I have elected to use a simple untyped, nullable string.
.../Entity/Client.php
public function getClient_birthdate() : ?\DateTimeImmutable
and
public function setClient_birthdate(?\DateTime $client_birthdate): void
...src/Invoice/Entity/Client.php...
/**
* #Column(type="date", nullable=true)
*/
private $client_birthdate = '';
The value accepted from coalface __form uses a string so initialize ClientForm.php's private ?string $client_birthdate = null with a string
not a DateTime function.
Question mark before ?\DateTime allows for null value. Use consistently in function declaration as well as seen below.
...src/Invoice/Client/ClientForm.php
public function getClient_birthdate(): ?\DateTime
{
if (isset($this->client_birthdate) && !empty($this->client_birthdate)){
return new DateTime($this->client_birthdate);
}
if (empty($this->client_birthdate)){
return $this->client_birthdate = null;
}
}
The above code can be reduced to:
public function getClient_birthdate() : ?\DateTime
{
// convert the input string on the form received by means of '$this->client_birthdate'
// back into DateTime so that Cycle can deal with it and
// save it in 'date' format in mysql behind the scenes
return new DateTime($this->client_birthdate);
}
Update 21 September 2022
Attributes are preferred now to annotations so above code has changed.
Essentially, to represent a DateTimeImmutable on a form it must be presented with the ->format() command. A suitable style of date must be between the brackets eg. Y-m-d or even d-m-Y. To accomplish this, additional code may be used eg.
__form.php
<div class="mb-3 form-group has-feedback">
<?php
$bdate = $datehelper->get_or_set_with_style($body['client_birthdate']);
?>
<label form-label for="client_birthdate"><?= $s->trans('birthdate') .' ('.$datehelper->display().')'; ?></label>
<div class="input-group">
<input type="text" name="client_birthdate" id="client_birthdate" placeholder="<?= ' ('.$datehelper->display().')';?>"
class="form-control input-sm datepicker" readonly
value="<?= null!== $bdate ? Html::encode($bdate instanceof \DateTimeImmutable ? $bdate->format($datehelper->style()) : $bdate) : null; ?>" role="presentation" autocomplete="off">
<span class="input-group-text">
<i class="fa fa-calendar fa-fw"></i>
</span>
</div>
</div>
Include the following datepicker jquery code in your layout file.
<?php
// https://api.jqueryui.com/datepicker
$js1 = "$(function () {".
'$(".form-control.input-sm.datepicker").datepicker({dateFormat:"'.$datehelper->datepicker_dateFormat()
.'", firstDay:'.$datehelper->datepicker_firstDay()
.', changeMonth: true'
.', changeYear: true'
.', yearRange: "-50:+10"'
.', clickInput: true'
.', constrainInput: false'
.', highlightWeek: true'
.' });'.
'});';
echo Html::script($js1)->type('module');
?>
Here is reference to the styles.
INVOICEPLANE SOLUTION
A Database Error Occurred Error Number: 1525 Incorrect DATE value: '0000-00-00' fix error 58 El error se debe al modo sql, que puede ser un modo estricto
solution permanent to Incorrect DATE value: '0000-00-00' change thsis data example > 1970-01-01
invoiceplane/application/modules/invoices/models/Mdl_invoices.php
or temporal solution mysql SET GLOBAL sql_mode = '';
ubuntu 20.04
mysql 8

Searching for n-th child in n-th parent

There is a strange behaviour when it comes to finding elements by xpath. The situation:
<body>
...
<div class="ingredients-group">
<div class="group-header">
<h3>Title 1</h3>
... other stuff
</div>
</div>
<div class="ingredients-group">
<div class="group-header">
<h3>Title 2</h3>
... other stuff
</div>
</div>
...
I want to check the text of the H3 tag on the second ingredient-group. So I did the following in Selenium:
WebElement group2 = driver.findElement(By.xpath("//div[#class='ingredients-group'][2]"));
WebElement title2 = group2.findElement(By.xpath("//h3"));
String titleText = title2.GetText();
The last statement returns "Title 1". I would expect it to return "Title 2".
Strangely, this statement returns "Title 2":
String titleText = driver.findElement(By.xpath("//div[#class='ingredients-group'][2]//h3")).getText();
I would like to use the first option (group2.findElement), because there are several other elements in the containers I would like to refer to without having to write the full xpath.
Any ideas on this?
Thanks
Use findElements to return a list of webelements (h3 tags) and then access them as you would any other list:
WebElement groups = driver.findElements(By.xpath("//div[#class='ingredients-group'][2]"));
WebElement theH3Tag = groups[0].findElement(By.xpath(".//h3")); //make this a relative xpath
String titleText = theH3Tag.GetText();
WebElement the2ndH3Tag = groups[1].findElement(By.xpath(".//h3")); //make this a relative xpath
String titleText = the2ndH3Tag.GetText();
Or loop through the list:
WebElement[] groups = driver.findElements(By.xpath("//div[#class='ingredients-group'][2]"));
for (WebElement group : groups) {
WebElement h3Tag = group.findElement(By.xpath(".//h3")); //make this a relative xpath
String titleText = h3Tag.GetText();
}

how to find element using xpath selenium

Here is my html of my element which i am able to find
<span data-bind="text: myAge()" xpath="1">Showing 1 of 25 people</span>
i could find above element using code like
[FindsBy(How = How.XPath, Using = "//*[#data-bind='text: myAge()']")]
I have another element in Html like which get dynamic ids
<input class="form-control" data-bind="textInput: code, attr: { id: 'myTable_code_' + $index() }" type="text" id="myTable_code_0" >
i tried to find same as above
[FindsBy(How = How.XPath, Using = "//*[#data-bind='textInput: code']")]
But i get error that "It is not able to find element"
How to fix this?
The data-bind attribute is "textInput: code, attr: { id: 'myTable_code_' + $index() }", you need to use all of it
[FindsBy(How = How.XPath, Using = "//*[#data-bind='textInput: code, attr: { id: 'myTable_code_' + $index() }']")]
Or partial attribute
[FindsBy(How = How.XPath, Using = "//*[contains(#data-bind, 'textInput: code')]")]

Get title, nav_title and subtitle

I want to print the fields title, nav_title and subtitle with Typoscript. I saw that there are several possibilities. E.g. data, field, levelfield, leveltitle, ...
Currently I'm using this code (because the only one which works for me so far):
lib.heading = TEXT
lib.heading.dataWrap = <p class="title"> {leveltitle:0} </p>
but I want something with alternatives like this
stdWrap.field = subtitle // nav_title // title
What is the correct way of retrieving these fields?
Edit:
[userFunc = user_isMobile]
page.headerData.10 = TEXT
page.headerData.10.value (
// ...
)
// ...
lib.heading = TEXT
#lib.heading.dataWrap = <p class="title"> {leveltitle:0} </p>
lib.heading {
field = title
wrap = <p class="title"> | </p>
}
lib.subpages = HMENU
lib.subpages {
// ...
}
[global]
The userfunction itself is a function in a php script (user_mobile.php). It makes a user agent detection for mobile devices and returns true or false.
field will get values from the current data which in your context is the data of the current page.
lib.heading = TEXT
lib.heading {
field = subtitle // nav_title // title
wrap = <p class="title">|</p>
}
leveltitle, leveluid, levelmedia, etc. allow you to retrieve some of the data from other pages in the rootline of the current page.
For more information see getText in the documentation.

select a record from a list-box using text in Protractor

I want to select the record from the list box using text. how can i use the filter function to select the particular record. I will be having many options but i want to select the value which i want by checking the text (e.g Spanish). I dont want to select value by index becoz if i do that i wont be able to verify test, moreover list gets updated. kindly help. below r my html code.
<ul class="addList">
<li ng-repeat="skill in availableSkills" ng-click="addSkillFunc(skill, $index)" class="ng-binding ng-scope">Mandarin</li>
<li ng-repeat="skill in availableSkills" ng-click="addSkillFunc(skill, $index)" class="ng-binding ng-scope">English</li>
<li ng-repeat="skill in availableSkills" ng-click="addSkillFunc(skill, $index)" class="ng-binding ng-scope">Spanish</li>
</ul>
Yea i can select the record by index. but i want something like selectbyvisibleText which is available in Selenium.
Finally got the solution. created a function SelectRowByCellValue and used to call it where ever i want by
SelectRowByCellValue(AGP.SkillList, Data.SkillSelect);
SkillList = element.all(by.css('Ul.addList li'));
SkillSelect = Value that u want to select. (Spanish)
this.SelectRowByCellValue = function (Elem, Texts) {
Elem.filter(function (element) {
return element.getText().then(function (text) {
if (text == Texts) {
element.click();
return false;
}
});
}).then(function (filteredElements) {
});
};