1

I am trying to click the Ask to join button in a google meet link(using my existing Google Chrome profile).This is the code:

options = webdriver.ChromeOptions()
options.add_argument(r"--user-data-dir=C:\\Users\\Pranil.DESKTOP-TLQKP4G.000\\AppData\\Local\\Google\\Chrome\\User Data")
browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)
delay = 15
browser.get('https://meet.google.com/tws-kcie-aox')
ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,)
time.sleep(5)
join_butt = WebDriverWait(browser, delay ,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.XPATH, '//*[@id="yDmH0d"]/c-wiz/div/div/div[5]/div[3]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div')))
join_butt.click()
print(join_butt.text)#this prints Ask to join

But the join button is not getting clicked. The most weird part 'Ask to join' text on the button does get printed in the last line. This means that selenium has reached the correct button. But still why does it not click the button?

EDIT: According to an answer by @Alin Stelian I updated the code as follows:

browser.get('https://meet.google.com/hst-cfck-kee')
browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 'd')
join_butt = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'Ask to join')]")))
join_butt.click()
print(join_butt)
print(join_butt.text)

This does work as both the print statements work...But the button isn't getting clicked. What is going wrong over here?

4 Answers4

1

When using Selenium for website that you don't own, NEVER rely on IDs or classes since they often change, especially for google's websites.

Best way to search for it is to find the element that presents the text that you know is wrote on the button (in this case Ask to join) and then get all the parents in a loop and check if some of them are buttons.

Like this:

WebElement buttonTextElement = browser.find_elements_by_xpath("//*[contains(text(), 'Ask to join')]")

then launch this javascript code in a cycle and stop it only if parent role attribute is equal to "button" or tag is "button"

WebElement parent = buttonTextElement;

WebElement parent = browser.execute_script("return arguments[0].parentNode;", parent) 

Then click().

I've wrote for u a fully working code in Java. I've used chromedriver version 85.

I shouldn't paste a whole code, but i'll do it for u :)

I saw that "Next" Button is the first parent so you don't need to go recursive. PS: Since i visited the italian webpage, make sure that the strings "Next" and "Ask to Join" are right char for char. Change them if u need to.

    import java.util.ArrayList;
    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.chrome.ChromeOptions;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            String email = "Your Google Email";
            
            String pass = "Your Google Password";
            
    
            System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
    
            ChromeOptions options = new ChromeOptions();
            
            
            // You need this to stop the page from askin u for mic
            options.addArguments("--use-fake-ui-for-media-stream");
            
            WebDriver driver = new ChromeDriver(options);
    
            
            //Login to Google
            driver.get("https://accounts.google.com/login");
            
            ArrayList<WebElement> emailinput = new ArrayList<WebElement>();
            
            ArrayList<WebElement> spans = new ArrayList<WebElement>();
            
             emailinput = (ArrayList<WebElement>) driver.findElements(By.tagName("input"));
             
             //Get all spans in page
             spans = (ArrayList<WebElement>) driver.findElements(By.tagName("span"));
            
             for(int i = 0; i < emailinput.size(); i++) {
                 
                 if(emailinput.get(i).getAttribute("type").equals("email")) { emailinput.get(i).sendKeys(email); break; }
                 
             }
             
             for(int i = 0; i < spans.size(); i++) {
                 
                 if(spans.get(i).getText().equals("Next")) {
                 WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                         "return arguments[0].parentNode;", spans.get(i)); parent.click(); break; }
                 
             }
             
             
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            ArrayList<WebElement> passinput = (ArrayList<WebElement>) driver.findElements(By.tagName("input"));
            
             for(int i = 0; i < passinput.size(); i++) {
                 
                 if(passinput.get(i).getAttribute("type").equals("password")) { passinput.get(i).sendKeys(pass); break; }
                 
             }
             
             spans = (ArrayList<WebElement>) driver.findElements(By.tagName("span"));
             
            
             for(int i = 0; i < spans.size(); i++) {
                 
                 if(spans.get(i).getText().equals("Next")) {
                 WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                         "return arguments[0].parentNode;", spans.get(i)); parent.click(); break; }
                 
             }
             
             try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             


//Create a Meet room and put here its URL
             driver.navigate().to("https://meet.google.com/dxz-dbwt-tpj");
             
             try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             
             spans = (ArrayList<WebElement>) driver.findElements(By.tagName("span"));
                
             for(int i = 0; i < spans.size(); i++) {
                 
                 if(spans.get(i).getText().equals("Ask to Join")) {
                 WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                         "return arguments[0].parentNode;", spans.get(i)); parent.click(); break; }
                 
             }
            
        }
    
    }

                      
  • The parent code that you have written doesn't work bro..It returns None so if I try to click it gives me this error AttributeError: 'NoneType' object has no attribute 'click' @Edoardo Rosso –  Sep 13 '20 at 18:47
  • `join_butt = WebDriverWait(browser, delay ,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.XPATH, '//span[contains(text(),\'Ask to join\')]'))) print(join_butt) join_butt.click()` @Edoardo Rosso this the exact snippet –  Sep 13 '20 at 19:49
  • This is absolutely not what i told u to try –  Sep 13 '20 at 20:23
  • Anyway you can add me on Discord SierraLevante#2544, i've enough experience with Selenium to help you :) –  Sep 13 '20 at 22:40
  • I am srry sir..some other answer suggested me the code that I posted in ur reply...but I tried the python version is of ur java code too..It didnt work. This was the code I tried: `buttonTextElement = browser.find_elements_by_xpath("//*[contains(text(), 'Ask to join')]") parent = buttonTextElement parent = browser.execute_script("return arguments[0].parentNode;", parent)` –  Sep 14 '20 at 08:17
  • anyways I will contact you on discord @Edoardo Rosso –  Sep 14 '20 at 08:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/221456/discussion-between-edoardo-rosso-and-pranil). –  Sep 14 '20 at 14:16
1

For further automating projects - avoid finding elements by id when the value is generated programmatically - it will not help you. Also, long xpaths is bad for your project performance.

The performance level of locators is -> ID, CSS, XPATH.

join_butt = WebDriverWait(browser, delay ,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.XPATH, '//span[contains(text(),'Ask to join')]')))

later edit next time don't ignore exceptions - it will help you to see your error syntax, I tested myself the below code.

join_butt = WebDriverWait(browser, delay).until(
    EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'Ask to join')]")))
driver.execute_script("arguments[0].click();", join_butt)

If the chrome browser doesn't allow you to log in - here is a trick

  1. Run your code
  2. In that browser go to StackOverflow
  3. Login w/ your account
  4. Quit the browser
  5. Run again your code - now you'll be logged in automatically in your google account.
Alin Stelian
  • 861
  • 1
  • 6
  • 16
  • I tried to use this code..The button doesn't get clilcked..But the strange part is that it does get printed when i tried to print it –  Sep 13 '20 at 18:53
  • @Pranil - give it a try again, I updated the code and it worked for me. – Alin Stelian Sep 14 '20 at 10:31
  • the code absolutely works!! I tried to print the button and the text inside it: `join_butt = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'Ask to join')]"))) print(join_butt) print(join_butt.text)` All of it is getting printed –  Sep 19 '20 at 10:27
  • Sir but the problem is that when I am trying to click the button using `join_butt.click()` it isnt getting clicked..What can be the problem? @Alin Stelian –  Sep 19 '20 at 10:31
  • yeah it does get printed..But the button doesn't get clicked.. –  Sep 19 '20 at 10:36
  • Try this driver.execute_script("arguments[0].click();", join_butt); instead of join_butt.click() – Alin Stelian Sep 19 '20 at 10:59
  • Use browser instead of driver – Alin Stelian Sep 19 '20 at 11:05
0

You can use the quickest path 
//span[contains(text(),'Ask to join')]

or from your code correct xpath
//*[@id="yDmH0d"]/c-wiz/div/div/div[4]/div[3]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/span/span

your xpath in the Code
//*[@id="yDmH0d"]/c-wiz/div/div/div[5]/div[3]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div
Anmol Parida
  • 672
  • 5
  • 16
0

To print the text Ask to join you need to induce WebDriverWait for the visibility_of_element_located() and you can use the following Locator Strategy:

  • Using XPATH and get_attribute():

    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//span[text()='Ask to join']"))).get_attribute("innerHTML"))
    
  • Using XPATH and text attribute:

    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//span[text()='Ask to join']"))).text)
    

You can find a relevant discussion in How to retrieve the text of a WebElement using Selenium - Python


To click on the element with text Ask to join you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following Locator Strategy:

  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "//span[text()='Ask to join']"))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

Outro

Link to useful documentation:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352