chromeless- Clicking on an element in the next page is not working - chromeless

On one of my tests I log in and move to the next page.
In the next page when I try to click on the profile element with .click nothing seems to be happening.
When I use the .exists function it returns false.
Why can't chromeless recognize element after changing the DOM?
async func(){
try {
this.chromeless
.goto(this.url)
.click(this.switchToLogIn)
.type(this.email, this.emaillAddressInput)
.type(this.password, this.passwordInput)
.click(this.logInButton )
.click(this.myProfile)
.screenshot()
}
catch(err) {
console.log(err)
}

Anything that was not already available in the DOM tree when the previous action in the chain was performed (with the exception of goto() and possibly some other methods) has to be waited for using the wait() method.
So, assuming that this.myProfile is a CSS selector string for an element to be clicked:
// Unchanged code omitted
.click(this.logInButton)
// Since the previous click loads a new page and/or shows new content, we need to wait
.wait(this.myProfile)
.click(this.myProfile)
Alternatively, the implicitWait Chromeless constructor option could be set to true, as long as that does not affect anything else negatively.

Related

Can HTAs be used to automate web browsing?

I am new to HTAs. I just read https://msdn.microsoft.com/en-us/library/ms536496%28v=vs.85%29.aspx and am a bit confused.
Can I use HTAs to automate browsing? Say I want to download a web page and fill in a form automatically, i.e. from a script. How would an HTA help me do this, if at all? It's important that the JavaScript code in the downloaded page is run as usual. I should be able to enter somehow and fill in the form after it has finished initializing, just as if I were a human agent.
First, you need to open an IE window, as follows:
var IE = new ActiveXObject("InternetExplorer.Application");
Then navigate the IE window to the webpage you want:
IE.Navigate("www.example.com");
Wether your IE window is visible or invisible, it's up to you. Use Visible property to make it visible:
IE.Visible = true;
Then, you should wait until the webpage is completely loaded and then run a function that takes your desired actions. To do so, first, get the HTML document object from the webpage using Document property of IE object, then repeatedly check the readyState property of document object. In the code below, it is assumed that you have a function named myFunc, which takes your desired actions on the webpage. (For example, modifying the contents of the webpage.)
var doc = IE.Document;
interval = setInterval(function() {
try
{
if (doc.readyState == "complete")
{
myFunc();
clearInterval(interval);
}
}
catch (e) {}
}, 1000);
In the function myFunc, you can do anything you want with the webpage since you have HTML document object stored in doc variable. You can also use parentWindow property to get the HTML window object.

Visibility of element- selenium webdriver

My script creates a new article: fills few fields and click "Submit button" at end of page.
I have written Click() function in util class like :
public void click(String xpathKey)
{
WebElement myDynamicElement = (new WebDriverWait(driver, 60))
.until(ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(prop.getProperty(xpathKey))));
try
{
myDynamicElement.click();
}
catch (Exception e)
{
e.printStackTrace();
throw e;
}
}
Waiting for visibility of element means it will wait until element will be visible on the page or on screen? My script clicks on submit button while it's not exactly visible on the page.
I am running this script since months and it's running perfectly fine. Suddenly it started giving error element is not clickable at point(213, 415). It never appeared before. Anyone has an idea, why it could have happened?
I have done many cases, where the element is not exactly visible, generally button at end of page. selenium does not scroll itself, it finds the element and performs operation.
Try this.
public void click(String xpathKey)
{
WebElement myDynamicElement = (new WebDriverWait(driver, 60))
.until(ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(prop.getProperty(xpathKey))));
try
{
Actions act = new Actions(driver);
act.moveToElement(myDynamicElement);
act.click();
act.build().perform();
}
catch (Exception e)
{
e.printStackTrace();
throw e;
}
}
The error message you are getting indicates that there is an element covering the element you are trying to click. If you read the error message carefully, it will tell you the HTML of the blocking element and that will help you find it on the page. Without more info, it's hard to tell exactly what the situation is but there are a few common causes.
You may have just closed a dialog/popup and it's not quite completely gone before you try to click. In this case, wait for some element that's part of the dialog to be invisible generally solves this problem.
There may be some wait/loading/spinner control that appears and disappears but you are clicking before it's completely gone. The solution is the same as #1, wait for some element that's part of the spinner to be invisible.
There may be some UI element like a header, footer, sidebar that is floating that covers the element you are trying to click if it's at the very bottom/top/etc of the page. These can be a real pain because you never know when the elements are going to align and be covered. One solution is to use JS to scroll the page a little more. For example, if you script is at the top of the page and you want to click something at the bottom. Doing a click will scroll the page to show that element but that puts the element at the very bottom of the page and under a floating footer. You try to click but catch the exception. Since you know you're at the bottom of the page, you scroll the page downwards by X pixels. This brings your desired element out from behind the floating footer and now you can click it.
NOTE: If you are going to click an element right after waiting for it, you should use .elementToBeClickable(locator) instead of .visibilityOfElementLocated(). It won't solve your current problem but it's a more complete and proper wait for what you are wanting to do.

see if the div is present or not in geb

We are using Geb for automation. I have spinner loaded before every page gets loaded. we are using waitFor() , but it takes a long time and the scripts are getting run more than the specified time.The DOM element is
<div classname="loader"></div>
i tried to see if the element is present.
if(!$(".loader").displayed== true)
{}
But i am getting error as ,
geb.waiting.WaitTimeoutException: condition did not pass in 40.0 seconds (failed with exception)
at geb.waiting.Wait.waitFor(Wait.groovy:138)
at geb.waiting.DefaultWaitingSupport.doWaitFor(DefaultWaitingSupport.groovy:51)
at geb.waiting.DefaultWaitingSupport.waitFor(DefaultWaitingSupport.groovy:46)
at geb.Page.waitFor(Page.groovy:516)
at geb.Browser.methodMissing(Browser.groovy:206)
at geb.spock.GebSpec.methodMissing(GebSpec.groovy:56)
at loaderSpec(loaderSpec.groovy:415)
Caused by: Assertion failed:
$(".loader").displayed== false
| | |
| true false
[[[ChromeDriver: chrome on XP (1b3943691dd96ebaf9098b1720c87ee9)] -> css
selector: .loader]]
at loaderSpec(loaderSpec.groovy:415)
at loaderSpec(loaderSpec.groovy:415)
at geb.waiting.Wait.waitFor(Wait.groovy:127)
... 6 more
I am not sure how to check if the div is present or not present. If I extend the time to wait for, I am getting element not found error.
Kindly let me know your input.
Are you checking that the div is visible while you are waiting for the spinner to go away?
I've had an issue exactly like this that plagued me. Here is the solution my coworkers and I came up with:
try{
waitFor(10) { element.isDisplayed() } //wait for spinner to kick in
waitFor() { !element.isDisplayed() } //wait for spinner to go away
} catch(WaitTimeoutException e) {
// if spinner loads & deloads faster than this code is reached
// then WTE will be caught and we dont need to handle the spinner any more
//println(e.printStackTrace())
}
Your boolean expression is more complicated than it needs to be, and in this case you might be noting (!) something you don't mean to be.
in general, you never need to compare booleans. (bool1==true) is the same as saying (bool1).
instead of saying
if(!$(".loader").displayed== true){}
just say:
if($(".loader").displayed){} //to check if the div is displayed
or
if(!$(".loader").displayed){} //to check if the div is not displayed
You can try with code if(!$(".loader")==undefined){}

How can I provide a tag that would run my cucumber background once for all scenarios?

I am using cucumber-js
I have some slides within the same url. For my feature, I want to provide the tester a way to open a url, and then have multiple scenarios on the same url:
The problem with the solution below is that the url re-opens for every scenario, reseting the slide to the start. I can never test each slide step as a separate scenario.
Any help or suggestion appreciated: example:
Feature: Valuation slide user journey - pre-reqisite As a developer I want to open the url /valuation/
Background:
Given I open the url "/valuation/"
Scenario: Test valuation slide button
Given the element "valuationIntro" is visible
When I click on the button "valuationIntro.cta"
Then I expect that element "valuationSlide1" becomes visible
Scenario: Test valuation autocomplete
Given the element "valuationSlide1.cta" has the class "invalid"
When I set "jk5 7kj" to the inputfield "valuationSlide1.autocomplete"
Then I expect that element "valuationSlide1.cta" does not have the class "invalid"
I understand I can use tags, but not entirely sure how I can use a tag to run a background once.
var executed = false;
var myStepDefinitionsWrapper = function () {
this.Given(/^I open the url "([^"]*)"$/, function (url) {
if (!executed)
// do some work with url
executed = true;
});
};
module.exports = myStepDefinitionsWrapper;
Just a simplification to make a point. I would use singletons with state.

Clearing input textbox using FuncUnit

I am writing FuncUnit for my application. I am browsing the application in Google Chrome. I have a textbox which is initially hidden. I need to make it visible and then clear the text already present in that textbox. I have the following code which makes the box visible but fails to clear the text in it.
S('#search').visible().clearText();
Can anyone tell what is wrong here?
Try to clear the textbox by typing - Ctrl+A and Delete.
var input = S('input.my-input');
input.type('[ctrl]a[ctrl-up][delete]', function() {
// Continue in test case after the text has been removed
});
Your statement is not accurate. visible() does not turn things visible. It is a wait function which waits for the source element to become visible before proceeding to the next action.
koalix's key sequence works. With the type() command you might need to first click into the text input before clearing it.
Try:
S('#search').visible().click().type('[ctrl]a[ctrl-up][delete]');
You could also try empty quotes <" ">
var input = S('input.my-input');
input.type('', function() {
// remove existing text
});
I don't know if you're still waiting for an answer.
I think you're not using visible() in the correct way.
In FuncUnit (see docs here), among other things, you can distinguish between "actions" and "waits". visible() is a wait, and should be used to wait for an element to become visible, like this:
S('#el').visible( function() {
// do something when element with id="el" becomes visible
});