I've built a PySimpleGUI app that selects a CSV,lets you select a Chrome version and then uses Selenium to do form inputs and submits. I now however need to refactor the drop down into a select like how the CSV does but cant get it to work, my code
import csv
import time
import threading
from selenium import webdriver
import PySimpleGUI as sg
import os
import sys
def resource_path(relative_path):
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def make_window(theme):
sg.theme(theme)
menu_def = [['&Application', ['E&xit']],
['&Help', ['&About']] ]
right_click_menu_def = [[], ['Exit']]
# Table Data
input_layout = [[sg.Menu(menu_def, key='-MENU-')],
[sg.Button("Open File")],
[sg.Text('Chrome Version')],
[sg.OptionMenu(values=('96', '97', '98'), k='-OPTION MENU-'),],
[sg.Button('Submit')]]
layout = [[sg.Text(' Email Automation', size=(38, 1), justification='center', font=("Helvetica", 16), relief=sg.RELIEF_RIDGE, k='-TEXT HEADING-', enable_events=True)]]
layout +=[[sg.TabGroup([[ sg.Tab('Setup CSV and Chrome Version', input_layout),
]], key='-TAB GROUP-')]]
return sg.Window('TEST', layout, right_click_menu=right_click_menu_def)
def main():
window = make_window(sg.theme())
# This is an Event Loop
while True:
event, values = window.read(timeout=100)
# keep an animation running so show things are happening
if event not in (sg.TIMEOUT_EVENT, sg.WIN_CLOSED):
print('============ Event = ', event, ' ==============')
print('-------- Values Dictionary (key=value) --------')
for key in values:
print(key, ' = ',values[key])
if event in (None, 'Exit'):
print("[LOG] Clicked Exit!")
break
elif event == 'About':
print("[LOG] Clicked About!")
sg.popup('TEST email automation',
'Select CSV file',
'Select Chrome Version',
'Submit',
'Powered By Me')
elif event == 'Popup':
print("[LOG] Clicked Popup Button!")
sg.popup("You pressed a button!")
print("[LOG] Dismissing Popup!")
elif event == "Open File":
print("[LOG] Clicked Open File!")
csv_file_selected = sg.popup_get_file('Choose your file')
# sg.popup("You chose: " + str(folder_or_file))
# print("[LOG] User chose file: " + str(folder_or_file))
def run_selenium(window, file, driver):
with open(file, 'rt') as csv_file:
csv_reader = csv.reader(csv_file)
#-------------------------------------------------------------------------------
# Web Automation
driver = webdriver.Chrome(executable_path=driver,service_log_path='/dev/null')
driver.get('https:/')
fname_field = driver.find_element_by_xpath('//*[@id="FIRSTNAME"]')
lname_field = driver.find_element_by_xpath('//*[@id="LASTNAME"]')
phone_field = driver.find_element_by_xpath('//*[@id="PHONE"]')
mail_field = driver.find_element_by_xpath('//*[@id="EMAIL"]')
deposit_field = driver.find_element_by_xpath('//*[@id="DEPOSIT"]')
submit = driver.find_element_by_xpath('//*[@id="sib-form"]/div[8]/div/button')
with open(file, 'rt', encoding='utf-8-sig') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=';')
next(csv_reader)
for line in csv_reader:
time.sleep(2.5)
fname_field.send_keys(line[10])
lname_field.send_keys(line[11])
mail_field.send_keys(line[13])
phone_field.send_keys(line[16])
deposit_field.send_keys(line[37])
submit.click()
# Not to update GUI in thread, but generate an event which will be processed in event loop.
window.write_event_value('Done', None)
def main():
# My GUI
window = make_window(sg.theme())
folder_or_file = None
cdriver = resource_path('chromedriver.exe')
# Using your path for all the drivers of all versions
paths = {
#'96': './chromedriver.exe',
'96': cdriver,
}
while True:
event, values = window.read(timeout=100)
# keep an animation running so show things are happening
if event not in (sg.TIMEOUT_EVENT, sg.WIN_CLOSED):
# print('============ Event = ', event, ' ==============')
# print('-------- Values Dictionary (key=value) --------')
for key in values:
print(key, ' = ',values[key])
if event in (None, 'Exit'):
# print("[LOG] Clicked Exit!")
break
elif event == 'About':
# print("[LOG] Clicked About!")
sg.popup('email',
'Select CSV file',
'Select Chrome Version',
'Submit',
'')
elif event == 'Popup':
# print("[LOG] Clicked Popup Button!")
sg.popup("You pressed a button!")
# print("[LOG] Dismissing Popup!")
elif event == "Open File":
#print("[LOG] Clicked Open File!")
folder_or_file = sg.popup_get_file('Choose your file')
# sg.popup("You chose: " + str(folder_or_file))
#print("[LOG] User chose file: " + str(folder_or_file))
elif event == 'Submit':
version = values['-OPTION MENU-']
if folder_or_file is None or version not in paths:
# print("No CSV file selected or wrong Chrome version selected")
continue
# Using thread to avoid long time job will block and cause GUI no response
threading.Thread(target=run_selenium, args=(window, folder_or_file, paths[version])).start()
# Disable Submit button to prevent submit again when threading
window['Submit'].update(disabled=True)
# print('[LOG] Run Selenium ...')
elif event == 'Done':
# Enable Submit button when thread done
window['Submit'].update(disabled=False)
# print('[LOG] End Selenium')
window.close()
main()
By allowing the chrome version to be picked it will make the whole process much easier instead of consistently rebuilding the app for every new chrome version