Selenium quasar app test element "click" issue - selenium

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"]')))

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 WebDriver -- Unable to click on hyperlink, click goes to the other element

I am unable to click on Website hyperlink, the click goes to Recently used pages.
Tried with CSS locator of Website icon [which works in the lower environment as it doesn't have Recently used pages] reference in it.
Tried with XPath Locator[including custom XPath], still, the click goes to another item.
Tried name locator.
Used Actions class for clicking.
Allowed the page to load completely by using sleep and WebDriver wait.
Located the element and send Enter keys, still Recently used pages is clicked.
Tried to click it using coordinates.
Thought of ChromeDriver issue but the issue persists in Firefox too.
Tried below XPath:
html/body/div/div[2]/div[2]/div[1]/a/div
//div[2]/div/a/div
Code snippet:
WebElement elementToClick = driver.findElement(By.cssSelector(".icon.siteadmin"));
elementToClick.click();
WebElement elementToClick = driver.findElement(By.cssSelector(".icon.siteadmin"));
(JavascriptExecutor)driver).executeScript("window.scrollTo(0,"+elementToClick.getLocation().x+")");
elementToClick.click();
WebElement elementToClick = driver.findElement(By.cssSelector(".icon.siteadmin"));
Actions actions = new Actions(driver);
actions.moveToElement(elementToClick);
actions.click().perform();
Actions builder = new Actions(driver);
builder.moveToElement(elementToClick, 40, 207).click().build().perform();
Result: It clicks on Recently Used Pages, and it yields a result of Recently used pages instead of Website.
UI Reference
Development Code Snippet
Hope It Helps you:
.//div[#id='box_2']/a/div[#class='icon siteadmin']/div[1]
Try the following:
driver.findElement(By.XPath(“//a[contains(#title, ‘Websites’)]”)).click()
If this doesn’t work use the above XPath in combination with one of the moves to element paths above and then use click.

Clicking label element that unfortunately contains a link

I'm running into an issue where I'm attempting to click on a checkbox. The app is written in AngularJS.
The checkbox can not be clicked, as technically the element is not visible. Using 'visible: false' does not help to get this box checked. I have also tried to use element.set(true)
The checkbox is within a label element that happens to also contain hyperlinks. Since Capybara/Selenium clicks on the middle of an element by default, I end up opening the hyperlink instead of marking the checkbox. Clicking within anywhere in the label (outside of the hyperlinks) checks the box successfully.
How can I achieve this?
I would recommend using JavascriptExecutor to click element. In case element is technically not visible Webdriver will not allow you to click it using API, as it tries to simulate real user actions. Nevertheless you have the option to execute JS directly, which doesn't really care.
This answer will help you with the code part:
https://stackoverflow.com/a/19934852/2998104
You would need to change ending slightly to:
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = driver.findElement(By.xpath("exact_locator_of_checkbox"));
js.executeScript("arguments[0].click()",element);
Of course no need to use only xpath, but anything that help you point to the checkbox directly.
Took me a little while but I figured out that I can avoid the Capybara API and use WebDriver's ActionBuilder.
def agree
source = find('label.terms-label').native
actionbuilder = page.driver.browser.action
actionbuilder.move_to(source, 0, 0).click.perform
end
By default, the Capybara API (as well as other native Selenium methods) will click in the center of the element. This will avoid that and will find the element and click it at (0, 0) coordinates.
As of Capybara 3.0.0, you can specify an offset when you call click on an element. So if you want to click the top-left corner of the element box, you'd say:
find('label.terms-label').click(x: 0, y: 0)
(Note, you must specify :x and :y if you specify either)
API Docs
Relevant commit

Selenium WebDriver - Have a button with two click zones and selenium is not clicking properly

Ok guys,
I'm QAing a claims application by guidewire and this is where im running into an issue.
The header area has header buttons and one of them is Claims, this button has two click zones, when you click on the claims label it recalls the last claim you had opened, when you click the down arrow, it opens and shows you more options.
The option I want to get to is "New Claim"
FirePath shows me two seperate xPaths
For the claim label: .//[#id='TabBar:ClaimTab-btnInnerEl']
For the downarrow label: .//[#id='TabBar:ClaimTab-btnWrap']
Once the downarrow is initiated the xpath for New Claim: .//*[#id='TabBar:ClaimTab:ClaimTab_FNOLWizard-textEl']
However when I write my script:
driver.findElement(By.xpath(".//*[#id='TabBar:ClaimTab-btnWrap']")).click();
driver.findElement(By.xpath(".//*[#id='TabBar:ClaimTab:ClaimTab_FNOLWizard-textEl']")).click();
it constantly keeps clicking on the wrong area and recalling the last claim and the script fails.
Here is a screencast of the behavior expected:
http://screencast.com/t/jtI1kGkfmXK
and here is basically what its doing
http://screencast.com/t/s2Q6VrbJl
What can I do to circumvent this issue? Its driving me crazy.
I took help from here
Try this code, and see if it works:
driver.findElement(By.xpath("//span[#id='TabBar:ClaimTab-btnWrap']")).sendKeys(Keys.ARROW_DOWN);
Well what I can gather is you have to get to the "New Claim" span and click it.
You can use Javascriptexecutor and directly click on the "New Claim" even without bringing it up. It helps that your intended element to be clicked has a unique id.
So you can use the following :
var js = Driver as IJavaScriptExecutor;
if (js != null)
{
js.ExecuteScript("document.getElementById('TabBar:ClaimTab:ClaimTab_FNOLWizard-textEl').click();")
}
You need to click open the window and wait for that to open.So,
Some wait needed after your first click
Then, You probably have to use switchTo() to set focus on the newly opened dropdown window. Some examples how to use it are here. After that use a textbase search for finding your element. Something like this.
EDIT:
I found text base search helps a lot in such cases.
try this:
driver.findElement(By.xpath(".//*[#id='TabBar:ClaimTab-btnWrap']")).click();
//use some static delay for now. But, really you should use some fluent wait for the element to appear.
driver.findElement(By.xpath(".//*[.='New Claim']")).click();
I figured it out! I had to use the actions class but this worked!
Its a little weird but it works
WebElement element = driver.findElement(By.linkText("Claim"));
Actions builder = new Actions(driver);
Action dropdown = builder.clickAndHold(element)
.sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN)
.build();
dropdown.perform();
driver.findElement(By.xpath(".//*[#id='TabBar:ClaimTab:ClaimTab_FNOLWizard-textEl']")).click();

Headless browser with mouseover event

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();