How to click a Vue/Vuetify card using selenium in python? - python

I am using selenium version 4.0.0, for reference.
I'm trying to click a Vuetify card element, which is acting as a button, but I running into an element not interactable: [object HTMLDivElement] has no size and location or just element not interactable errors. I have been able to solve similar problems with action chains in the past, but it doesn't seem to work with this.
This is the list element the button is contained within:
<li class="lu-li list-item" data-v-711d8d7a="" style="display: flex;">
<div class="addCard v-card v-card--link v-sheet theme--light" data-v-711d8d7a="" tabindex="0" onselectstart="return false;">
::before
<i class="v-icon notranslate btnAdd material-icons theme--light enableIcon" data-v-711d8d7a="" aria-hidden="true">
add
::after
</i>
</div>
</li>
The first things I tried was simply clicking on the element, and then clicking on the <i> element beneath it when that didn't work:
addQLButton = driver.find_element(By.CLASS_NAME, "addCard")
addQLButton.click()
addQLButton = driver.find_element(By.CLASS_NAME, "btnAdd")
addQLButton.click()
I have already tried using WebDriverWait on both the v-card <div> and <i> element to make sure they are available before being clicked, which it passes without any issues:
WebDriverWait(driver, timeout=10).until(lambda d: d.find_element(By.CLASS_NAME, "addCard"))
WebDriverWait(driver, timeout=10).until(lambda d: d.find_element(By.CLASS_NAME, "btnAdd"))
I have already tried using action chains to make sure the elements are visible (this has worked in the past with similar errors), but I still run into the same issue:
addQLButton = driver.find_element(By.CLASS_NAME, "addCard")
actions.move_to_element(addQLButton).perform()
driver.execute_script("arguments[0].click();", addQLButton)
addQLButton = driver.find_element(By.CLASS_NAME, "btnAdd")
actions.move_to_element(addQLButton).perform()
driver.execute_script("arguments[0].click();", addQLButton)
The elements are not in an iframe, and I am sure I have the correct window selected as I am still able to interact with its elements.
I am at a bit of a loss, any help would be much appreciated. I'm happy to answer any clarifying questions if I didn't explain the issue clearly enough.

I managed to get it working with some javascript:
js = "document.querySelector('.btnAdd').click();"
driver.execute_script(js)

Related

Selenium and HTML

I have been using selenium to try and scrape some info from a database of company data. The database is private and it requires a password so, unfortunately, I cannot share the whole python code, nor the whole HTML code.
Here's the part of the HTML code required for my problem
<li>
<a id="reportsForm:j_idt320:3:j_idt325" href="#" class="ui-commandlink ui-widget nav-item " onclick="PrimeFaces.addSubmitParam('reportsForm',{'reportsForm:j_idt320:3:j_idt325':'reportsForm:j_idt320:3:j_idt325'}).submit('reportsForm','_blank');return false;" target="_blank">
<span id="reportsForm:j_idt320:3:l2" data-hasqtip="reportsForm:j_idt320:3:tooltipID">Avaliação de Risco Plus</span></a>
</li>
In this part of the code, I need to click on a linked text, and I have tried countless ways (including implicit waits, finding elements by class name, id, xpath and so on...) and I have realised that the only way to locate the element is through the following command:
afg = driver.find_element_by_link_text('Avaliação de Risco Plus')
However, when I try to click on it, I run into the following error message:
Message: element click intercepted: Element Avaliação de Risco Plus is not clickable at point (550, 745). Other element would receive the click: <div id="fundo">...</div>
I understand python is not letting me click on this what I defined as afg, because it is intercepted by the link on href = "#". But that is exactly the link I want to click!
How can I solve this?
Thanks for your help :)
If it is still in view point, you can try with below code :
element_to_be_clickable = driver.find_element_by_link_text('Avaliação de Risco Plus')
ActionChains(driver).move_to_element(element_to_be_clickable).click().perform()
or
ActionChains(driver).move_to_element(driver.find_element_by_link_text('Avaliação de Risco Plus')).click().perform()

Finding/locating a clickable text by xpath in div/span format

I used the following line to click the Availability Grid button, but it failed to locate the element.
Class Sarsa-button-content is used everywhere so, I added text together to make it unique. However, it couldn't find it. What am I missing?
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='sarsa-button-content']/span[text()='Availability Grid']"))).click()
<div class="sticky-top-wrapper" style="top: 80px;">
<div class="site-filter-container" id="site-filter-container">
<a data-component="Button" class="sarsa-button view-by-availability-grid--button-tracker sarsa-button-primary sarsa-button-sm" href="/site/123456/availability">
<span class="sarsa-button-inner-wrapper">
<span class="sarsa-button-content">Availability Grid</span>
your xpath is wrong, try this:
//span[contains(#class, 'sarsa-button-content') and text() = 'Availability Grid']

Python Selenium: clicking a "visible" element using Selenium gives me an "element not visible" error

I am trying to test against this website. (https://www.phptravels.net/), and I want to test its Login feature. There is a "My Account" link, which needs to be clicked first to show the drop down of the Login and Sign up button. The HTML code is like this:
<li id="li_myaccount" class="">
<span class="ink animate" style="height: 137px; width: 137px; top: -10.7969px; left: -28.7344px;"></span><i class="icon_set_1_icon-70 go-right"></i> My Account <b class="lightcaret mt-2 go-left"></b>
<ul class="dropdown-menu">
<li><a class="go-text-right" href="https://www.phptravels.net/login"> Login</a></li>
<li><a class="go-text-right" href="https://www.phptravels.net/register"> Sign Up</a></li>
</ul>
</li>
When I try to click the "My Account" button, it throws an error msg saying "element not visible". I am confused because apparently this button is visible all the time. Here is the code:
elem = driver.find_element_by_xpath("//*[#id='li_myaccount']/a")
elem.click()
What is wrong with my code? Thank you.
I tried to interact with the My Account Link, which is shown in the right part of the navigation bar on the page (https://www.phptravels.net/). Using the locator //*[#id='li_myaccount']/a when I try to click the Link, using the Webdriver, I get the below error:
ElementNotVisibleException: Message: element not interactable
When I explored the html using Chrome's console and searched the element using the locator //*[#id='li_myaccount']/a, the My Account Link, which you want to click doesn't get highlighted.
Therefore further exploration led me to choose the locator //*[contains(#class,'navbar-nav navbar-right')]//*[#id='li_myaccount']/a which highlights the My Account Link.
Then I used the new locator to click My Account link, using the Webdriver and it works !
If you notice carefully, I just added preceding path in the locator that you shared to uniquely identify the My Account Link.
Change the xpath to this one:
(//*[#id='li_myaccount']/a)[2]
If you look at the source, there are actually 2 elements matching this locator - an <a> tag in some modal that's currently hidden, and the one you are trying to address; thus your issue, the method returns the first one, which is not the desired.
This xpath will return the 2nd element ([2]) from the set of responses (the () surrounding the looked-for value).

python element is no longer attached to the dom selenium

I get "element is no longer attached to the dom" exception even though the element is there and is clickable, I am trying to click the "next" arrow on ryanair website, the html for the next button is:
<li class="newer" ng-class="{'loadingsmall':loading}">
<a ng-disabled="loading" ng-click="loadMore(0, 'SelectInput$LinkButtonNext1', 1)"
title="Next Week" href="">
</a>
</li>
I located and clicked it in several methods:
elem = WebDriverWait(browser, 15).until(EC.element_to_be_clickable((By.XPATH,
"//a[#title='Next Week']")))
elem = browser.find_element_by_xpath("//a[#title='Next Week']")
elem.click()
and:
area = browser.find_element_by_xpath("//a[#title='Next Week']")
action = webdriver.ActionChains(browser)
action.move_to_element(area) action.click(area) action.perform()
and:
elem = browser.find_element_by_link_text('>')
elem.click()
all work fine if I have no action in between, but once I tell selenium to click on other elements on the page (I do not move to other pages, I stay on the same page and show some dynamic content) the "next" link only works the first time around, and then gives me the exceptions, help would be so greatly appreciated! :)
You're still on the same page but the DOM's elements have changed due to some AJAX actions & calls, so you're forced to re-detect your object using:
elem = browser.find_element_by_link_text('>')
If you don't do that, it is more than likely that you'll get a
StaleReferenceException
For more info

Selenium: Timing inconsistency with WebDriverWait & click

I have a set of divs to show/hide content in a typical accordion style. The HTML looks like this;
<div class="accordionContainer">
<div class="accordion">
<h3>Click This</h3>
<div class="accordionContent" style="display:none">
</div>
</div>
<div class="accordion">
<h3>Click This</h3>
<div class="accordionContent" style="display:none">
</div>
</div>
</div>
I've then got my python to select that first H3 and then open a link that is in accordionContent.
WebDriverWait(ff, 10).until(lambda driver : driver.find_element_by_xpath("id('main_content')/div[3]/div/div/div[1]/h3[1]")).click()
WebDriverWait(ff, 10).until(lambda driver : driver.find_element_by_xpath("id('main_content')/div[3]/div/div/div[1]/div/p/a")).click()
I have ran this & seen it work. However most of the time it fails. The first div gets clicked (I can see a little arrow on it rotate to show the content but it seems to get clicked twice as it immediately returns to default and I get the error;
[exec] selenium.common.exceptions.ElementNotVisibleException: Message: u'Element is not currently visible and so may not be interacted with'
Oddly though when it can be seen to be clicked, but not open, if you call the same click() line a second time it works.
Can that second xpath be advanced to check that the accordionContent has been changed to display: block?
This xpath should work:
"//div[#class='accordionContainer']/div[#class='accordion'][1]/div[#class='accordionContent' and contains(#style, 'block')]"
or if the structure is pretty safe, could do:
"//div[#class='accordionContainer']/div[1]/div[contains(#style, 'block')]"
Note: I am assuming that it is just a typo in the example that the closing tag for the 'accordion' div is supposed to be a closing tag (rather than the opening tag seen).

Categories