Headless browser with mouseover event - selenium

I'm using phantomjs with selenium to click a button. Unfortunately, that button is disabled, and only enabled when there's mouseover/click event in the real browser. Is there any way to simulate that in PhantomJS?
I tried ActionChains, but it still doesn't work (the button is still disabled):
ActionChains(driver).move_to_element(button).perform()

I believe that your problem is not PhantomJS, but rather Actions. When you use actions, you should link all of your actions together, and then perform the action. In this case, it would be:
ActionChains(driver).move_to_element(button).click(button).perform();

Please try the following code:
browser.actions().mouseMove(element(by.css(button))).perform();

Related

Element not interacable

I have this error "element not interactable" When I try to click a drop down list with selenium. However in debug mode, when I inspect ( press F12 ) before the break points and I continue to run then the test is passed. So my question is Why the elements can be clicked and what should I do to prevent the situation again. Many thanks!
You have to add wait / delay before accessing the elements to let the elements be fully loaded on the page before accessing them.
The simplest way is to add hardcoded sleep, like
time.sleep(5)
The better way is to use explicit way implemented by expected conditions.
Few things to note down,
Always launch browser in full screen mode.
driver.maximize_window()
this code should be written before driver.get()
Whenever you get element not interactable, try to use action chains to click or send_keys :
something like this :-
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(driver)
action.move_to_element('your web element here').click().perform()
Make sure that using Selenium, the desired web element should be in Selenium view port.
in order to resolve this, you may have to scroll down to let Selenium know where exactly the element is.

Selenium quasar app test element "click" issue

I have an app made with Quasar. I make e2e tests with python selenium using firefox. I log in and then would like to logout. To perform this I need as usually click on profile icon to show the menu and select Logout.
The issue is that whatever I tried the menu doesn't appear. The code looks as follows.
#pytest.mark.nondestructive
def test_must_login_and_logout_properly(logged_in_selenium, wait):
driver = logged_in_selenium
avatar = wait.until(EC.presence_of_element_located((By.XPATH, '//header//img[#alt="Profile image"]/ancestor::button/parent::span')))
# "natively" via selenium
ActionChains(driver).pause(1).move_to_element(avatar).click().perform()
# via javascript
driver.execute_script('document.evaluate(\'//header//img[#alt="Profile image"]/ancestor::button/parent::span\', document).iterateNext().dispatchEvent(new Event("click"))')
The above code doesn't work UNTIL I really click this element with the mouse. By putting time.sleep(10) at first line in test function and click. After that any method via avatar.click() or execute_script(...) works fine.
I also have an option to use PyAutoGUI to find the avatar on the screen and perform that click, but I don't like this variant.
-- UPDATE
I found out why it behaves like this, but still don't know how to work this around. Initially (after page load) click event handler is not attached to //header//img[#alt="Profile image"]/ancestor::button/parent::span element. It only appears after manual click in this area.
Any ideas?
You didn't share a link to this page, so I can only guess.
I would try to:
Wait for element visibility, not just existance.
Try to remove click from ActionChains action.
Add a short delay between moving to the element and click on it..
Still not sure, but possibly this will work
avatar = wait.until(EC.visibility_of_element_located((By.XPATH, '//header//img[#alt="Profile image"]/ancestor::button/parent::span')))
ActionChains(driver).pause(1).move_to_element(avatar).perform()
time.sleep(0.2)
avatar.click()
UPD
Try this:
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[#class='q-avatar']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Logout']"))).click()
Eventually it was necessary to click the element twice. Due to maybe Quasar implementation detail.
#pytest.mark.nondestructive
def test_must_login_and_logout_properly(logged_in_selenium, wait):
driver = logged_in_selenium
avatar = wait.until(EC.visibility_of_element_located((By.XPATH, '//header//img[#alt="Profile image"]/ancestor::button/parent::span')))
ActionChains(driver).pause(1).move_to_element(avatar).click().pause(0.5).click().perform()
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Logout']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[text()="You have logged out"]')))

Codeception ElementNotVisibleException error, unable to select option, or click

I am unable to interact with an element using browser tests. It says the element is not interact-able, or not visible. This doesn't happen in Acceptance
Sometimes this solution doesn't work because the element is unavailable for some other cryptic reason.
We just had a situation where we couldn't use a <select> element to pick one of the options.
Further more, there was behaviour that was being triggered by the "change" event when the option was selected.
We were able to solve it like this.
$js = "jQuery('#chosen-option-quantity-2').val('2').trigger('change');";
$I->executeJS($js);
so the first command selects the option, and the second triggers the change event.
I hope that helps some one, even if it is me in the future.
The problem that is happening here is that the html element is being hidden by something, probably css somewhere. Because it is hidden (display:none), WebDriver can't see it, and therefore can't interact with it.
In order to fix this problem, you need to use JS to un-hide the element.
use this $I->executeJS('jQuery("#your-css-selector").show()');
This doesn't happen in Acceptance tests because PHP Browser looks at the Page Source, and so can see everything, while WebDriver see's what a user see's on the browser.
You may use PhpBrowser
It works only with HTML then how PhantomJs emulate the real browser
But, with PhpBrowser you can't see what see your browser (only HTML such I said)
Another way, try executeJs with PhantomJs as it said before

Selenium ie driver cannot switch to window popup

Trying to use the ieDriver.switchTo().window(windowHandle) method to switch to a popup window but my test script stops and does not proceed.
When I close the window manually i get the error
org.openqa.selenium.NoSuchWindowException: Unable to get browser
I know the window exists because I used the ieDriver.getWindowHandles() method to retrieve it.
All my protected mode settings are the same, I even tried to use the 'INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS' technique to no avail. Any other suggestions?
I'm running selenium 2.32.0 with IE9 on a Windows 7 machine.
Above code isfor handling window pops.
If you want to handle javascript popups like alerts, or confrmation popup, you need to use
driver.SwitchTo.alert().accept();
or
driver.SwitchTo.alert().dismiss();
hope it'll help you
maybe the popup is generated, with iframe, then you have to use switchTo.frame();
You should do something like:
WebDriverWait webDriverWait= new WebDriverWait(driver, 5000);
webDriverWait.until(ExpectedConditions.alertIsPresent());
driver.switchTo().alert().accept();
First you will initialize a WebDriverWait object that will allow you to wait until some condition is met, in this case - alert is present.
Then, the driver will be switched to this alert,

selenium webdriver is clearing out fields after sendKeys had previously populated them

The webpage that I'm testing is using knockout. On other pages on our site that are not currently using knockout I'm not having the same problem. The scenario I have is where the page opens, I enter in various required fields and click the save button. At some point between when it enters a value in the last text field and when it clicks the save button the fields that previously had values become cleared out, and thus the script can't continue. Here is an example of the code that I'm running:
driver.findElement(By.id("sku")).clear();
driver.findElement(By.id("sku")).sendKeys(itemNo);
driver.findElement(By.id("desktopThankYouPage")).clear();
driver.findElement(By.id("desktopThankYouPage")).sendKeys(downloadUrl);
driver.findElement(By.id("mobileThankYouPage")).clear();
driver.findElement(By.id("mobileThankYouPage")).sendKeys(mobileDownloadUrl);
driver.findElement(By.id("initialPrice")).clear();
driver.findElement(By.id("initialPrice")).sendKeys(initialPrice);
driver.findElement(By.id("submitSiteChanges")).click();
Like I said, between the time it enters text in the last field and the time it clicks save the fields that previously had text in them get cleared out, and thus my test fails. The problem is it doesn't always happen. Sometimes the test runs fine, other times it doesn't.
I've tried putting Thread.sleep(x); all over the place to see if pausing at certain points would fix the problem. I also have tried using javascript to wait in the background for any ajax that might be running. Also have the implicit wait of driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS). None of it seemingly has made any difference.
I'm running version 2.13 of selenium server and all my tests run on Firefox 8.
Any help on this would be greatly appreciated!
Firefox has a bug which prevents some events from being executed while the browser window is out of focus. This could be an issue when you're running your automation tests - which might be typing even if the window is out of focus.
The point is that knockout model updates are triggered (by default) with the change event. If it's not being executed, it's underlying model won't be up-to-date.
To fix this issue I triggered the change event "manually", injecting javascript into my tests.:
//suppose "element" is an input field
element.sendKeys("value");
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("$(arguments[0]).change();", element);
As you might have noticed, I'm using jQuery to trigger the change event. If you're not using jQuery on your app, you can check here how to trigger it using vanilla javascript.
Hope that helps somebody.
I had the exact same problem. I would guess also that your code works fine in Chrome but not firefox, and that it always works when you do it manually?
Anyway, the problem is likely to be that Selenium doesn't really behave the same way as a real user, and doesnt trigger the same events. When you "submit" the form, it sometimes won't have executed the "change" event on a text area, meaning that it won't have changed.
I had the same problem testing Backbone.modelbinding, which uses the "change" event to update the model from the form. Knockout also uses the "change" event, but fortunately it can also use the "keyup" event. See valueUpdate in the docs:
<input data-bind="value: someValue, valueUpdate: 'keyup'" />
Anyway, that reproducibly solved it for me, and didnt need any sleeps once I had that done. The downside is that you'd be running the event more than is necessary in production, in order to make tests work. Another downside is that you if you want to run some code when a value changes, you'll now get one event per keypress instead of one per field change, which sucks sometimes.
There is another solution, which is to make Selenium fire the change event yourself, for example: Selenium IE change event not fired. It's also suboptimal, but what can you do.
You could also try putting the focus on a button before you click it. Don't know if that will work, I haven't tried it.
I was facing the same issue, while using JavaScriptExecutor for sending keys to text fields.
Using below code in IE (same code is working with chrome):
(JavascriptExecutor) driver.executeScript("arguments[0].value = '" + value + "';", element);
After updating the code to simple "sendKeys()" method, it resolved my issue:
element.sendKeys("some text");