Q:

Multithreading in python selenium

I want to open and login 5 tabs concurrently without delay in between in tabs. I have tried:
import threading
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def openurl(threadId):
    print(threading.currentThread().getName(),' Thread')
    url = ('https://www.facebook.com/')
    print(url)
    driver.execute_script("window.open('{0}')".format(url))
    #driver.title(threadId)
    time.sleep(0.1)

    driver.set_window_size(920, 680)
    driver.find_element(By.ID, "email").send_keys("xx")
    driver.find_element(By.ID, "pass").send_keys("yy")
    driver.find_element(By.ID, "loginbutton").click()

if __name__=='__main__':
    driver = webdriver.Chrome()
    windows_before  = driver.current_window_handle
    for i in range(5):
        t1 = threading.Thread(name=i,target=openurl, args=(i,))
        t1.start()
        t1.join()

but it is throwing:

Traceback (most recent call last):   File
  "C:\Users\1024983\AppData\Local\Programs\Python\Python37\lib\threading.py",
  line 870, in run
      self._target(*self._args, **self._kwargs)   File "C:\Users\1024983\AppData\Local\Programs\Python\Python37\fb-thread.py",
  line 30, in openurl
      driver.find_element(By.ID, "email").send_keys("xx")   File
      raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such
  element: Unable to locate element: {"method":"css
  selector","selector":"[id="email"]"}   (Session info:
  chrome=78.0.3904.108)

If I increased sleep time, there is a delay in-between tabs. I tried to navigate using driver.title but my case title is same for all tabs.

A:

It is example uses threads to run separated browsers which fill form and set True in list buttons to inform that login button is ready to click. When all browsers set True in list buttons then all of them click buttons. 
It seems that it runs amost a the same time - maybe only system has some to makes so many connections at the same time.
I used list buttons to synchronize all threads. Every thread get number to have own place in list. I don't use append(True) because I'm not sure it can be thread-safe.
import time
from selenium import webdriver
from threading import Thread

def func(number):
    driver = webdriver.Chrome()
    #driver.set_window_size(920, 680)
    driver.get(url)

    driver.find_element_by_id("email").send_keys("xx")
    driver.find_element_by_id("pass").send_keys("yy")
    b = driver.find_element_by_id("loginbutton")

    buttons[number] = True
    print(buttons)

    # wait for other buttons
    while not all(buttons):
        pass

    print('click', number)
    b.click()

# ---

url = 'https://www.facebook.com/'

number_of_threads = 5

#buttons = [False * number_of_threads] # create place 
buttons = []

threads = []

for number in range(number_of_threads):
    t = Thread(target=func, args=(number,)) # get number for place in list `buttons`
    t.start()
    threads.append(t)
    buttons.append(False) # create place 

for t in threads:
    t.join()

EDIT: The same with threading.Barrier(5) and 5 threads will have to run barrier.wait() to move forward.
import time
from selenium import webdriver
from threading import Thread, Barrier

def func(barrier):

    driver = webdriver.Chrome()
    #driver.set_window_size(920, 680)
    driver.get(url)

    driver.find_element_by_id("email").send_keys("xx")
    driver.find_element_by_id("pass").send_keys("yy")
    b = driver.find_element_by_id("loginbutton")

    print('wait for others')
    barrier.wait()

    print('click')
    b.click()

# ---

url = 'https://www.facebook.com/'

number_of_threads = 5

barrier = Barrier(number_of_threads)

threads = []

for _ in range(number_of_threads):
    t = Thread(target=func, args=(barrier,)) 
    t.start()
    threads.append(t)

for t in threads:
    t.join()

