Why doesn't my Selenium session stay logged in? - python-3.x

I'm working on using selenium to sign into GitHub and create a repository. A similar project that I had found, after login used "https://github.com/new" to go to the repo creation page. However, when I try to do that, it returns to an empty login page with the following url: "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fnew".
I'm pretty lost and haven't found a good reason yet for why this would be happening.
PS. This is connected to a shell script, but the shell script is doing what it's supposed to so I didn't attach that code along with the Python that's being troublesome.
import sys
from selenium import webdriver
browser = webdriver.Safari()
def createProj():
folder_name = str(sys.argv[0])
browser.get("https://github.com/login")
try:
login_button = browser.find_elements_by_xpath("//*[#id='login_field']")[0]
login_button.click()
login_button.send_keys("Insert email here")
pass_button = browser.find_elements_by_xpath("//*[#id='password']")[0]
pass_button.click()
pass_button.send_keys("Insert password here")
submit_button = browser.find_elements_by_xpath("//*[#id='login']/form/div[4]/input[9]")[0]
submit_button.click()
except:
print("You're already signed in, no need to log in.")
browser.get("https://github.com/new")
if __name__ == "__main__":
createProj()

Related

Session expired error immediately after logging in using Selenium Chrome WebDriver in Python

I am trying to login to the webpage below and my code is able to do that for me with no errors. But the moment the code hits the "Login" button, the following error message appears:
how do I resolve this? I am using a Chrome Browser with Selenium in python to automate this process. I am getting the same error while using the edge browser as well.
I am using the following code to achieve this:
chrome_driver_path = r"C:\Users\selenium\chromedriver_win32\chromedriver.exe"
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(executable_path=chrome_driver_path,options=options)
wait = WebDriverWait(driver, 5)
#open the webpage and enter the email id on the login page
driver.get("https://auth.slido.com/login? auth_state=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkIifQ.eyJqdGkiOiJmNzZjNzNmNC1hODcyLTQ5NzYtOTBiMS1jZWM5NTJiNTRmNmYiLCJjbHVzdGVyX2lkIjoiZXUxIiwiY2xpZW50SWQiOiI2OTFmNGMxNi1kZTM1LTExZWItYmE4MC0wMjQyYWMxMzAwMDQiLCJwcm9tcHQiOiJjb25zZW50IiwicmVkaXJlY3RVcmkiOiJodHRwczovL2FkbWluLnNsaS5kby9vYXV0aC1jYWxsYmFjayIsInNjb3BlIjoib3BlbmlkIG9mZmxpbmVfYWNjZXNzIGVtYWlsIHByb2ZpbGUgc3lzdGVtOnNjb3BlOmFjcXVpcmUiLCJzZXNzaW9uIjp7ImlzQXV0aE4iOmZhbHNlLCJpc0ludGVybmFsIjp0cnVlfSwic3RhdGUiOiJleUp5WldScGNtVmpkQ0k2SW1GSVVqQmpTRTAyVEhrNWFGcEhNWEJpYVRWNllrZHJkVnBIT0haYVdGcHNZbTVTZWlKOSIsImNsYWltcyI6e30sImlhdCI6MTY3NTE3NTk3MSwiZXhwIjoxNjc1MTc3NzcxLCJpc3MiOiJodHRwczovL2F1dGguc2xpZG8uY29tIn0.Y7WjeXgVCoZMKTfbJ2iy-O7UQn8_-vz_ZhgwsyuyrxervrMnBRYN-oCGEnRI5SnQDlRxif1qBSpDUxNSOOGnv4wgCTLRfq-X-AE7dHeOFcvAdGmmCl_HGGEpQ5plA7yT7f7pMt6xibK2ZhwNL7KwY_OUgVpgz0ROcSv7wBQVNGcx2Am0NfGZw1eDEhBfyiUTktGqTDVyQfmNAB3F7G7PtvgoXEikLLTZBqBY93d5w4RrjxIt6tzdiNpBKwwMulXmSzr0OGnLiRCQXsNfLyst028Hmoq_HsxFLICTKxZTOkelFB83XM1zGRnUkjCOCT-EhQbT0I-hJvQccdlbCdjXKg")
#first accepting all cookies before moving to our actual search
driver.find_element(By.XPATH,"/html/body/div[2]/div[2]/button[2]").click()
time.sleep(2)
#assigining the username
driver.find_element(By.ID,"email").send_keys("xyz#abc.com")
#then clicking on the continue button and move forward
driver.find_element(By.XPATH, "/html/body/auth-root/auth-layout/div[3]/div/auth-login/div/div/form/auth-recaptcha/div/div[2]/button").click()
time.sleep(2)
#now we need to assing the password to login
driver.find_element(By.ID,"password").send_keys("####")
#click on the login button next
driver.find_element(By.XPATH, "/html/body/auth-root/auth-layout/div[3]/div/auth- login/div/div/form/auth-recaptcha/div/div[2]/button").click()
time.sleep(2)
print("Logged in")

Unable to fetch web elements in pytest-bdd behave in python

So, I'm in the middle of creating a test-automation framework using pytest-bdd and behave in python 3.10.
I have some codes, but the thing is, I'm not able to fetch the web element from the portal. The error doesn't say anything about it. Here is the error I'm getting in the console.
Let me share the codes here too for better understanding.
demo.feature
Feature: Simple first feature
#test1
Scenario: Very first test scenario
Given Launch Chrome browser
When open my website
Then verify that the logo is present
And close the browser
test_demo.py
from behave import *
from selenium import webdriver
from selenium.webdriver.common.by import By
# from pytest_bdd import scenario, given, when, then
import time
import variables
import xpaths
from pages.functions import *
import chromedriver_autoinstaller
# #scenario('../features/demo.feature', 'Very first test scenario')
# def test_eventLog():
# pass
#given('Launch Chrome browser')
def given_launchBrowser(context):
launchWebDriver(context)
print("DEBUG >> Browser launches successfully.")
#when('Open my website')
def when_openSite(context):
context.driver.get(variables.link)
# context.driver.get(variables.nitsanon)
print("DEBUG >> Portal opened successfully.")
#then('verify that the logo is present')
def then_verifyLogo(context):
time.sleep(5)
status = context.driver.find_element(By.XPATH, xpaths.logo_xpath)
# status = findElement(context, xpaths.logo_xpath)
print('\n\n\n\n', status, '\n\n\n\n')
assert status is True, 'No logo present'
print("DEBUG >> Logo validated successfully.")
#then('close the browser')
def then_closeBrowser(context):
context.driver.close()
variables.py
link = 'https://nitin-kr.onrender.com/'
xpaths.py
logo_xpath = "//*[#id='logo']/div"
requirements.txt
behave~=1.2.6
selenium~=4.4.3
pytest~=7.1.3
pytest-bdd~=6.0.1
Let me know if you need any more information. I'm very eager to create an automation testing framework without any OOPs concept used.
Just the thing is, I'm not able to fetch the web elements. Not able to use find_element(By.XPATH, XPATH).send_keys(VALUE) like methods of selenium.

How to use Device Farm desktop browser session with Python

I'm trying to run a Selenium test in Python using Device Farm desktop browser session, but with the lack of resources (official or not), and my lack of knowledge, I can't figure it out.
I used these documentations:
https://docs.aws.amazon.com/devicefarm/latest/testgrid/getting-started-migration.html
https://selenium-python.readthedocs.io/getting-started.html#simple-usage
I installed the GeckoDriver, and ran the following code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()
I saw a web browser appear for about a second.
I then decided to use Device Farm. I setup my AWS env vars, tested the connectivity, and ran the following code:
import boto3
import pytest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class test_url:
def setup_method(self, method):
devicefarm_client = boto3.client("devicefarm", region_name="eu-west-1")
testgrid_url_response = devicefarm_client.create_test_grid_url(
projectArn="arn:aws:devicefarm:us-west-2:1234567890:testgrid-project:some-id-string",
expiresInSeconds=300)
self.driver = webdriver.Remote(
"http://www.python.org", webdriver.DesiredCapabilities.FIREFOX)
# later, make sure to end your WebDriver session:
def teardown_method(self, method):
self.driver.quit()
Here's the result:
$ pytest -s
====================================================================================== test session starts =======================================================================================
platform linux -- Python 3.8.2, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/eric/nuage/devicefarm-poc
collected 0 items
===================================================================================== no tests ran in 0.07s ======================================================================================
I saw nothing happen in the AWS Management Console.
Why did no test run? Shouldn't this code perform an URL test? Shouldn't something happen in the AWS Management Console when I run this?
There appears to be a few issues with your code.
According to the pytest documentaion it seems like you need to put your tests into a file starting with the name test and to put your tests in methods starting with the word test as well. This is why none of your code is executing.
The line driver = webdriver.Firefox() tries to create a local firefox driver. What you want is a remote driver using the URL that AWS Device Farm provides (which you do at the line self.driver = webdriver.Remote("http://www.python.org", webdriver.DesiredCapabilities.FIREFOX)
The line self.driver = webdriver.Remote("http://www.python.org", webdriver.DesiredCapabilities.FIREFOX) is incorrect. The first argument is supposed to be the URL of the remote endpoint used to execute your tests. In this case, its AWS Device Farm's endpoint that is given in the CreateTestGridUrl API response. Selenium is basically just a REST service, so it performs actions via REST calls to an endpoint that tells the driver which actions to perform.
AWS Device Farm is currently only in us-west-2.
I suggest you go through the pytest, Selenium, and AWS docs again to understand how it all works together. Its not too complex, but it may get confusing if you do not know how all the working parts interact with each other.
Here's a "minimal" example with pytest to get you started.
import logging
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.keys import Keys
import boto3
import pytest
PROJECT_ARN = # Your project ARN
# Currently, AWS Device Farm is only in us-west-2
devicefarm = boto3.client('devicefarm', region_name='us-west-2')
remote_url = devicefarm.create_test_grid_url(
projectArn=PROJECT_ARN,
expiresInSeconds=600 # 10 minutes. Increase to longer if needed
)['url']
#pytest.fixture(scope="module") # Specify "module" to reuse the same session
def firefox_driver(request):
# Start fixture setup
logging.info("Creating a new session with remote URL: " + remote_url)
remote_web_driver = webdriver.Remote(command_executor=remote_url, desired_capabilities=DesiredCapabilities.FIREFOX)
logging.info("Created the remote webdriver session: " + remote_web_driver.session_id)
yield remote_web_driver # Returns driver fixture and waits for tests to run
logging.info("Teardown the remote webdriver session: " + remote_web_driver.session_id)
remote_web_driver.quit()
logging.info("Done tearing down")
#pytest.mark.usefixtures("firefox_driver")
def test_search_in_python_org(firefox_driver):
driver = firefox_driver
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
# driver.close() // This is done in the fixture instead of here now
#pytest.mark.usefixtures("firefox_driver")
def test_aws_console_title(firefox_driver):
driver = firefox_driver
driver.get("https://aws.amazon.com/")
assert "Amazon Web Services" in driver.title
if __name__ == '__main__':
unittest.main()

Multithreading with Selenium using Python and Telpot

I'm coding my first telegram bot, but now I have to serve multiple user at the same time.
This code it's just a little part, but it should help me to use multithread with selenium
class MessageCounter(telepot.helper.ChatHandler):
def __init__(self, *args, **kwargs):
super(MessageCounter, self).__init__(*args, **kwargs)
def on_chat_message(self, msg):
content_type, chat_type, chat_id = telepot.glance(msg)
chat_id = str(chat_id)
browser = browserSelenium.start_browser(chat_id)
userIsLogged = igLogin.checkAlreadyLoggedIn(browser, chat_id)
print(userIsLogged)
TOKEN = "***"
bot = telepot.DelegatorBot(TOKEN, [
pave_event_space()(
per_chat_id(), create_open, MessageCounter, timeout=10),
])
MessageLoop(bot).run_as_thread()
while 1:
time.sleep(10)
when the bot recive any message it starts a selenium session calling this function:
def start_browser(chat_id):
global browser
try:
browser.get('https://www.google.com')
#igLogin.checkAlreadyLoggedIn(browser)
#links = telegram.getLinks(24)
#instagramLikes(browser, links)
except Exception as e:
print("type error: " + str(e))
print('No such session! starting webDivers!')
sleep(3)
# CLIENT CONNECTION !!
chrome_options = Options()
chrome_options.add_argument('user-data-dir=/home/ale/botTelegram/users/'+ chat_id +'/cookies')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--lang=en')
print("Starting WebDrivers")
browser = webdriver.Chrome(options=chrome_options)
start_browser(chat_id)
return browser
and then this one check if the user is logged:
def checkAlreadyLoggedIn(browser, chat_id):
browser.get('https://www.instagram.com/instagram/')
try:
WebDriverWait(browser, 5).until(EC.element_to_be_clickable(
(By.XPATH, instagramClicks.buttonGoToProfile))).click()
print('User already Logged')
return True
except:
print('User not Logged')
userLogged = login(browser, chat_id)
return userLogged
and if the user is not logged it try to log the user in whit username and password
so, basically, when I write at the bot with one account everithing works fine, but if I write to the bot from two different account it opens two browser, but it controll just one.
What I mean it's that for example, one window remain over the google page, and then the other one recive two times the comand, so, even when it has to write the username, it writes the username two times
How can I interract with multiple sessions?
WebDriver is not thread-safe. Having said that, if you can serialise access to the underlying driver instance, you can share a reference in more than one thread. This is not advisable. But you can always instantiate one WebDriver instance for each thread.
Ideally the issue of thread-safety isn't in your code but in the actual browser bindings. They all assume there will only be one command at a time (e.g. like a real user). But on the other hand you can always instantiate one WebDriver instance for each thread which will launch multiple browsing tabs/windows. Till this point it seems your program is perfect.
Now, different threads can be run on same Webdriver, but then the results of the tests would not be what you expect. The reason behind is, when you use multi-threading to run different tests on different tabs/windows a little bit of thread safety coding is required or else the actions you will perform like click() or send_keys() will go to the opened tab/window that is currently having the focus regardless of the thread you expect to be running. Which essentially means all the test will run simultaneously on the same tab/window that has focus but not on the intended tab/window.
Reference
You can find a relevant detailed discussion in:
Chrome crashes after several hours while multiprocessing using Selenium through Python

Trying to combine flask and guizero

So i was trying flask when i got an funny idea. If i could combine guizero with my server i could make like a console for my simple server. So i began working when i stumbled over 2 problems.
Here's my code:
from flask import Flask, render_template
from guizero import App, PushButton, Text, TextBox
app = Flask(__name__)
app.debug = True
console = App(title='web server')
text_input = "no message"
def message():
text_input = textbox.get
textbox.clear
header = Text(console, text="Web server console", size= 50)
description = Text(console, text="type message here:")
textbox = TextBox(console)
button = PushButton(console, text="send", command=message)
#app.route('/')
def index():
return render_template('index.html', text= text_input)
#app.route('/next')
def next():
return render_template('game.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
app.display()
The template index.html is just simply a paragraph with {{text}}. It does show the "no message" string.
Now i'm experiencing 2 problems with this code.
1: If i run it it only starts the server, but when i run it again it gives the "already in use" error and then opens the gui
2: If i use the gui the website won't update when i push the button, i think because the gui doesnt run in the same instance of the script as the server. And if it does i don't think the debug function works with variables in the script.
running the server on a raspi 3B on ethernet if that is important
i'm very new to flask and html so maybe i won't understand your answer but i'd be glad if you could help
I also am new to Flask but I think you have to make a new thread (either for the Flask app or the GUI). This makes sure that both Flask and the GUI can run simultaneously. Now you try to run two loops at the same time and tht doesn't work.

Resources