How can I check if element is present in laravel dusk test? - laravel-dusk

In the below code, I want to check if the element is present at XPath, then only it should execute code.
if($browser->driver->findElement(WebDriverBy::xpath('/html/body/div[1]/div/section/div[3]/div[2]/div/table/tbody/tr['.$i.']/td[2]'))!==null)
{
$sort=$browser->driver->findElement(WebDriverBy::xpath('/html/body/div[1]/div/section/div[3]/div22]/div/table/tbody/tr['.$i.']/td[2]'))->gettext();
echo $sort;
}
Or else please suggest if there is another way to check element is present in laravel dusk.
P.S. I tried whenAvailable method but it couldn't help me in this case.

Found another better and workable solution:
if ($browser->element('#IDString')) {
}

Laravel-Dusk provides two straight-forward method assertVisible (5.4+) and assertPresent (5.6+).
assertVisible makes sure the element is in the visible view-port of the web-page.
assertPresent makes sure the element exists in the source code of the page.
You can pass in any html selector to check if the element if visible.
/** #test */
public function assert_that_home_page_opens_up(){
$this->browse(function ($browser) {
$browser->visit('/')
->assertPresent('#my-wrapper')
->assertVisible('.my-class-element')
});
}
xpath
The above methods can only be used if you have a selector (class or id) for the element that you are looking for.
If you need to check if an element exists at a particular xPath, you can make use of driver instance on $browser object, to directly call the methods provided by Facebook Web-driver API:
$this->assertTrue(
count(
$browser->driver->findElements(WebDriverBy::xpath('//*[#id="home-wrapper"]'))
) > 0);
Source : https://www.5balloons.info/how-to-check-if-element-is-present-on-page-using-laravel-dusk/

/*
* check element exist
* if it doesn't not exist
* will throw exception
*
* #retuen void
*/
try {
$this->browse(function (Browser $browser) {
$elementExist = $this->assertNotNull($browser->element('#idString'));
if (empty($elementExist)) {
\Log::info('element exist')
}
}
}
catch (\Exception $e) {
\Log::info($e->getMessage());
}

When I want to check to see if an element exists, I usually do something like this:
$this->browse(function (Browser $browser) {
$this->assertNotNull($browser->element('#idString'));
}

Related

If selenium can't find an element do something

I'm using maven and selenium for testing in java. I would like to know if there is a way to call a function every time a test fails. I already have a function that takes an screenshot of the browser. I would like to use it every time selenium throws NoSuchElNoSuchElementExeption for example.
Is there an "easy" way to implement this?
Thank you!
You can create a method to find the element and implement a try-catch block inside that to catch the NoSuchElementException. Call your function to take the screenshot inside that catch block.
e.g.
public WebElement findElement(By locator) {
try {
WebElement element = driver.findElement(locator);
return element;
} catch (NoSuchElementException nse) {
// call the function to take a screenshot
}
}
I eventually found this solution to the problem:
https://darrellgrainger.blogspot.com/2011/02/generating-screen-capture-on-exception.html?m=1
Consists on using WebDriverEventListener.

Selenium - Java - How to check button is enabled or not?

I have tried so many times isenabled property but it always return "true" as the button is disabled on the page but it still return "True"
Please suggest the workaround to handle this?
Here is the code:
public void OpenSearchPage_and_verifyaddtofavoriteslink() throws InterruptedException
{
try
{
driver.navigate().to(favouritepagelink);
driver.findElement(FavoritesCheckBoxSelectAll).click();
//verify condition if product exist on favorites page
if(driver.findElement(FavoritesDelConditionCheck).isEnabled())
{
System.out.println("Enter in condition");
}
else
{
System.out.println("Out of condition");
}
}
catch(Exception ex)
{
System.out.println("SearchPage not opened: " +ex.getMessage());
}
}
Suggestions:
There can two reasons for getting this issue:
i) Issue with object
ii) Issue with the property
I) Issue with object: We can ensure we are using the right object for the button
and refresh the object before performing the operation
ii) Issue with property: Please check if some other property other then enabled is indicating this behaviour by verifying the html code behaviour.
Problem resolved :)
I have used getattribute to get class name then apply condition based on class attribute and its working fine.
Thank you all for the help :)

Check if a WebElement is stale without handling an exception

I'm currently checking to see if a WebElement is stale by doing the following:
public static boolean isStale(WebElement element) {
try {
element.click();
return false;
} catch (StaleElementReferenceException sere) {
return true;
}
}
This is the same as the solution offered to this question:
Check for a stale element using selenium 2?
However, this seems rather messy to me. Is there a cleaner way that I can check if an element is stale, without having to throw and catch an exception?
(Also, as a side, if I have to stick with throwing and catching an exception, is there something better to do than clicking/sending keys/hovering to throw said exception? I might have a WebElement that I don't want to do any of these actions on, as it may inadvertently affect something else.)
Webdriver itself uses the try/catch-construction to check for staleness as well.
from org.openqa.selenium.support.ui.ExpectedConditions.java:
public static ExpectedCondition<Boolean> stalenessOf(final WebElement element) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver ignored) {
try {
// Calling any method forces a staleness check
element.isEnabled();
return false;
} catch (StaleElementReferenceException expected) {
return true;
}
}
#Override
public String toString() {
return String.format("element (%s) to become stale", element);
}
};
}
The isEnabled() check is better than using a click action - clicking an element might cause unwanted side effects, and you just want to check the element's state.
I know this already has an accepted answer and I don't know the bigger context of how you use the staleness check but maybe this will help you or others. You can have ExpectedConditions.stalenessOf(WebElement) do the work for you. For example,
WebElement pageElement = driver.findElement(By.id("someId"));
WebDriverWait wait = new WebDriverWait(webDriver, 10);
// do something that changes state of pageElement
wait.until(ExpectedConditions.stalenessOf(pageElement));
In this case, you don't have to do pageElement.click(), etc. to trigger the check.
From the docs, .stalenessOf() waits until an element is no longer attached to the DOM.
References: ExpectedConditions
Classic statement for C# to check staleness of web element
protected bool IsStale
{
get { return ExpectedConditions.StalenessOf(webElement)(WebDriver); }
}
I don't fully understand what you want to do. What do you mean by 'messy' solution?
Maybe you can use an explicite wait an as expected condition stalenessOf in combination with not.
But every solution with that don't seems stable to me.
What I do is, that I have an clicking routine in a helperclass, the idea is like:
public void ClickHelper(WebDriver driver, By by){
int counter = 1;
int max = 5;
while (counter <= max) {
try {
WebElement clickableWebElement = driver.findElement(by);
clickableWebElement.click();
return;
} catch (StaleElementReferenceException e) {
System.out.print("\nTry " + counter + " with StaleElementReferenceException:\n" + e.getMessage() + "\n");
}
versuche++;
}
throw new RuntimeException("We tried " + max + " times, but there is still an Exception. Check Log!");
}
Be careful, I just entered this by simplyfying my own methode (there are some more checks and personally I use xpath and not by etc). There might be some typo-mistakes, but i guess you will understand the basic idea. Since I use this Helpermethode, I don't have to care about Staleness of webelements. You can alter the max-value, but personally I think, if the website is such unstable, that the Element is stale so much, I would talk to the developer, because this would not be a good website.
This should work without dependency of display/ enabled:
def is_element_on_page(element):
try:
element.get_attribute('')
return True
except StaleElementReferenceException:
return False

Cucumber/Selenium throwing more detailed errors when element not found

Is there a way for Selenium/Cucumber to throw a more descriptive error when an element is not found? Currently it only throws:
The element could not be found (Selenium::WebDriver::Error::NoSuchElementError)
I'd like to also include the locator.
It depends how your test fixture code is designed and structured. You can wrap FindElement code inside try/catch block. Something like:
Public void TestMethod(string elementId)
{
try
{
driver.FindElement(By.CssSelector(elementId));
}
catch(NoSuchElementException exception)
{
Assert.Fail("Can't find the element in the page. The element is: " +elementId)
}
}

Best way to find out if jqGrid is loaded and ready with Selenium

How are you finding out if jqGrid is loaded and ready to be used, via selenium.
Some details :
Im using C# driver
I have a method : new WebDriverWait(driver, new TimeSpan(0, 0, 0, 30)).Until(x => loadingdissapearedcondition) which im using to wait until Loading.. element is gone.
I also sometimes use this script :
private const string script = #"return ($('#{0}').jqGrid('getGridParam', 'reccount') !=x undefined) && ($('#{0}').jqGrid('getGridParam', 'reccount') != 0) && (!$('#load_{0}').is(':visible')) && (!$('#busyIcon').is(':visible'))";
private readonly string waitScript;
waitScript = string.Format(script, jqGridId);
public void WaitUntilLoadIconDissappears()
{
driver.WaitUntil(MAXWAIT, Wait);
}
public bool Wait()
{
var executeScript = ((IJavaScriptExecutor) driver).ExecuteScript(waitScript);
bool result;
bool tryParse = bool.TryParse(executeScript.SafeToString(), out result);
return tryParse && result;
}
to find if jqGrid has records and loading done.
I require something better - as even the above two does not make driver wait until load finishes, if we are using local data for jqGrid. Im also curious what is the best way, or at the minimum, how others are dealing with this problem.
I never used Selenium before, so I'm not sure that I understood your problem correctly. jqGrid will be first initialized and then (optionally) the data can be loaded from the server. During the initializing stage the original <table id="grid"></table> element will be converted to relatively complex HTML fragment which is the grid. At the end of the initialization the DOM element of the table (the $("#grid")[0]) will get the expando grid.
So you can use the test like
if ($("#grid")[0].grid) {
// grid is initialized
}
to determine that the grid is already initialized. jqGrid uses the same test internally (see here for example).
Here is solution for Java and jqgrid.
If grid data is not loaded yet then right pager has no value, so simply check its length. Methods such as isElementPresent, isDisplayed etc. seems not to work for grid right pager object. It's always present in page code while ajax, but text value is set when dynamic data is loaded.
public void waitForGridPagerRight(String gridName) throws Exception {
for (int second = 0;; second++) {
if (second >= 15) {
fail("Timeout.");
}
try {
if (driver
.findElement(By.id("pager_" + gridName + "_right"))
.getText().length() > 2)
break;
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
Not sure why #Oleg's answer didn't work for me. It seemed like grid was being populated even before the ajax call was being made. It appears there's some change in newer versions maybe. It look like the last thing to happen in the ajax call is that the "loading" block is hidden, so instead I find that element and check it's display attribute a la:
def wait_for_jqgrid(self, t=20):
def check_jqgrid(driver):
#the last thing jqgrid does after the ajax call is to turn off the loading div
#so we find it and check to see if its display attribute is no longer set to 'none'
script = 'pid = $.jgrid.jqID($(".ui-jqgrid-btable").get(0).p.id); return $("#load_"+pid).get(0).style.display == "none";'
return driver.execute_script(script)
WebDriverWait(self.driver, t).until(check_jqgrid)
When the loading div is hidden, we are done. This is python but the same javascript bit should work in Java or whatever.