Problem with Filedialog in Python, Selenium 'NameError' - python

I work on this Projekt where I try to get Links from a Website and I got it to work after 2-3 Weeks and now my Task is to build an GUI with TKinter. The Problem is that I ask the User to select the Driver that is needed for the Selenium Operation, that grabs the Links from the Website
So this is my Code and probably the Problem is easy but I'm just stuck at the part from coderetter() to code() where I give the Filepath to the Driver it always says: "NameError: name 'save' is not defined" and I tried everything
The Problem occurs on the last line by executable_path that where i want to let the User choose the path.
Has anyone got any similar kind of problem or does someone maybe see the problem here?
import csv
from tkinter import *
from tkinter import filedialog
from multiprocessing import Process
def Fenster():
root = Tk()
root.title("MS-Search Grabber")
w = Label(root, text='W!')
driverButt = Button(text='Chrome-Driver', command=coderetter)
FileSave = Button(text='Save CSV', command=saveFile)
StartB = Button(text='Start Process', command=proSt)
w.pack()
driverButt.pack()
FileSave.pack()
StartB.pack()
root.mainloop()
def coderetter():
file = filedialog.askopenfilename()
def saveFile():
save = filedialog.asksaveasfile()
return save
def proSt():
p2 = Process(target=code)
p2.start()
def code():
why = saveFile(save)
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('headless')
chrome_options.add_argument('window-size=1920x1080')
chrome_options.add_argument('disable-gpu')
driver = webdriver.Chrome(executable_path=why, options=chrome_options)
if __name__ == "__main__":
file = ''
driver= ''
save = ''
p1 = Process(target=Fenster)
p1.start()

The use of global will enable file and save strings to be available to other parts of your code.
By using global in saveFile, you do not need a return
This means Filesave button will also function correctly since buttons do not accept returned information.
def coderetter():
global file
file = filedialog.askopenfilename()
def saveFile():
global save
save = filedialog.asksaveasfile()
def proSt():
p2 = Process(target=code)
p2.start()
def code():
saveFile()

Related

Python Multithreading Selenium

I am writing a code in Tkinter with a button that starts 6 selenium chrome instances, each with a different url. The goal is : the drivers have to be initiated in the fastest possible way and every driver instance has to reenter its specific url (refresh) every 4 seconds. Every driver is attached to a class, that contains the wanted url. I tried this with threads:
import tkinter as tk
import threading
import os
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
browsers = []
class Browser:
def __init__(self, url, session_file):
self.url = url
self.session_file = session_file
def manipulate_browser(browser):
browser.driver = webdriver.Chrome(ChromeDriverManager().install())
while True:
browser.driver.get(browser.url)
time.sleep(4)
def start_browsers():
for browser in browsers:
browser.thread = threading.Thread(target=manipulate_browser, args=(browser,))
browser.thread.start()
if __name__=='__main__':
lock = threading.Lock()
threads = []
urls = 'https://google.com', 'https://facebook.com', 'https://instagram.com', 'https://snapchat.com', 'https://stackoverflow.com', 'https://amazon.com', 'https://microsoft.com'#, 'https://stackoverflow.com', 'https://youtube.com', 'https://yahoo.com'
for url in urls:
session_file = 'session_' + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(10))
newBrowser = Browser(url, session_file)
browsers.append(newBrowser)
root = tk.Tk()
button_start_browsers = tk.Button(root, command=start_browsers, width=50, height=4, bg='red', text='Start Browsers')
button_start_browsers.pack()
And this works just fine, but I want to add some options and capabilities to the driver, in the manipulate_browser function . Like so:
import tkinter as tk
import threading
import os
import time
import random, string
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from multiprocessing.pool import ThreadPool
browsers = []
class Browser:
def __init__(self, url, session_file):
self.url = url
self.session_file = session_file
def manipulate_browser(browser):
global lock
with lock:
caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "none"
chrome_options = webdriver.ChromeOptions();
current_dir = os.path.dirname(os.path.abspath(__file__))
os.mkdir(current_dir + '\\' + browser.session_file)
chrome_options.add_argument(r'--user-data-dir=' + current_dir + '\\' + browser.session_file + '\\selenium')
chrome_options.add_argument("--window-size=750,750")
browser.driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options, desired_capabilities=caps)
while True:
browser.driver.get(browser.url)
time.sleep(4)
def start_browsers():
for browser in browsers:
browser.thread = threading.Thread(target=manipulate_browser, args=(browser,))
browser.thread.start()
if __name__=='__main__':
lock = threading.Lock()
threads = []
urls = 'https://google.com', 'https://facebook.com', 'https://instagram.com', 'https://snapchat.com', 'https://stackoverflow.com', 'https://amazon.com', 'https://microsoft.com'#, 'https://stackoverflow.com', 'https://youtube.com', 'https://yahoo.com'
for url in urls:
session_file = 'session_' + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(10))
newBrowser = Browser(url, session_file)
browsers.append(newBrowser)
root = tk.Tk()
button_start_browsers = tk.Button(root, command=start_browsers, width=50, height=4, bg='red', text='Start Browsers')
button_start_browsers.pack()
After implementing this, it doesn't work anymore : meaning : sometimes, I get this error selenium.common.exceptions.WebDriverException: Message: unknown error: cannot parse internal JSON template: Line: 1, column: 1, Unexpected token. And all the threads seem to work on just one driver (the last one). I believe this is because the threads mix with each other so I have to use a lock, but putting this line browser.driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options, desired_capabilities=caps) under the lock will affect drastically my speed, that I need. I also understand that I have to use ThreadPool, for avoiding thread mixing and I tried it, but it freezed the GUI app. Another option that others suggest is implementing queue with threads, which I am not very familiar with. I also thought of trying multiprocessing, but the maximum numbers of processes depends on every machine characteristics, from my understanding, and maybe I want to start more processes than that. How can I workaround this situation to achieve my goal? What is the best way?
(Note : I've done plenty of research regarding my issue, but I still couldn't figure it out. Any help is welcomed !)
EDIT :
Due to multiple testing, I figured out that the line chrome_options.add_argument(r'--user-data-dir=' + current_dir + '\\' + browser.session_file + '\\selenium') may cause all the problems. This line keeps the chrome sessions all in one icon and I really like this feature and I wouldn't like getting rid of it. How can I overcome the issue, knowing this information? Any help would be appreciated !

How to prevent the mobile application closing and re-opening each time a test case is running?

I am performing mobile application automation using Appium with Python. I am also in need of creating HTML reports. I am wanting to create multiple test suites too. And all these works, except for one problem.
My problem is that the application closes and re-opens in every test case. How can I fix this? Thanks in advance.
(Please note that this is a sample code I'm putting on here.)
from adb.client import Client as AdbClient
import HtmlTestRunner
import datetime
import os, sys
import glob
import unittest
from appium import webdriver
from time import sleep
from appium.webdriver.common.touch_action import TouchAction
PLATFORM_VERSION = '8.1.0'
class Q_suite1_01(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '8.1.0'
desired_caps['deviceName'] = 'Samsung Galaxy J7 Max'
devices = AdbClient(host= "127.0.0.1", port= 5037).devices()
for device in devices:
desired_caps['udid'] = device.serial
desired_caps['appPackage'] = 'com.testapp'
desired_caps['appActivity'] = 'com.testapp.MainActivity'
url = "http://localhost:{}/wd/hub".format(4723)
self.driver = webdriver.Remote(url, desired_caps)
def install(self):
print 'ABDC!'
def run_app(self):
try:
x = self.driver.is_app_installed('com.quallogi')
if x is True:
print 'App is already installed.'
else:
print 'App is not installed.'
except:
print 'App not installed'
def signin(self):
sleep(5)
self.driver.find_element_by_xpath('//*[contains(#text,"Login") and contains(#class, "android.widget.TextView")]').click()
print 'Sign'
def testcase_Install_app(self):
self.install()
def testcase_Run_app(self):
self.run_app()
def testcase_SignIn(self):
self.signin()
# def testcase_Install_app(self):
# self.install()
# self.run_app()
# self.signin()
#
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
result = []
suite1= unittest.TestLoader().loadTestsFromTestCase(Q_suite1_01)
result.append(HtmlTestRunner.HTMLTestRunner(output='./HTML Reports/'
+ str(datetime.date.today())).run(suite1))
print(result)
At the first I want to recomend you to look at the Appium capability "noReset" - "Don't reset app state before this session." (true, false).
If i right understand you question. What do you meant "application closes and re-opens in every test case"? Can you describe it more detail?

tkinter watch clipboard GetMessage no return value

i want to Monitoring Clipboard app for win10.
like: when we copy text 00-22-33-11-22 Mac Address from notepad.exe,tk's window get text and translate mac address to machine name.
but tkinter have no clipboard events.
so i call win32api
i search pywin32 document , found win32clipboard.SetClipboardViewer
but Creating a Clipboard Viewer Window is very complex
i search MSDN , found AddClipboardFormatListener is recommended 。this method is simpler to SetClipboardViewer. MSDN Creating a Clipboard Format Listener
i used it ,but GetMessage always be blocked
import tkinter as tk
import time
import threading as thrd
import win32gui
import win32clipboard
import win32api
import win32con
import ctypes
from ctypes.wintypes import MSG
from ctypes import byref
def selfevent(root):
print("thrd start")
hwnd = int(root.frame(), 16)
done = ctypes.windll.user32.AddClipboardFormatListener(hwnd)
print("done=", done)
if done:
wmsg = None
print("begin GetMessage")
wmsg = win32gui.GetMessage(None, 0, 0)
# wmsg = MSG()
# ctypes.windll.user32.GetMessageA(byref(wmsg), 0, 0, 0)
print("GetMessage", wmsg.message(), win32api.GetLastError())
if wmsg:
print("msg=", wmsg)
print(ctypes.windll.user32.RemoveClipboardFormatListener(hwnd))
if __name__ == "__main__":
root = tk.Tk()
root.title("tktest")
root.geometry("600x400")
# root.bind("<<foo>>", vectrl)
print("begin")
txt = tk.Entry(root)
txt.pack()
bt2 = tk.Button(root, text="GetClipboardSequenceNumber", command=lambda: print("sn=", win32clipboard.GetClipboardSequenceNumber()))
bt2.pack()
t = thrd.Thread(target=selfevent, args=(root,))
t.setDaemon(True)
t.start()
root.mainloop()
how to get WM_CLIPBOARDUPDATE message?
my english is very poor.
run result:
begin
thrd start
done= 1
begin GetMessage
i copy anything , GetMessage are always blocked ,no return.
AddClipboardFormatListener is successful.
GetMessage(hwnd or None,0,0)
The results are the same.
I have studied GetMessage, in the main thread, using AddClipboardFormatListener to register, using GetMessage is normal, but in the new thread, GetMessage always has no return value.
I have reviewed many of the forum posts, and basically mentioned that there are problems with multithreading of tk.
#stovfl mentioned the post, I read. I think that after is not a good idea.
after consumes main thread performance and affects UI display.
Use event to communicate on the page in vb.net. So I searched the tk documentation and found event_generate.
The test found that event_generate does not seem to be affected by multithreading.
Through the forum posts, I have completed some of the defects of event_generate and given my solution.
My code demonstrates monitoring the clipboard and launching a multi-threaded task with the button (traversing all the files in the path directory, finding the total number of files), the UI display is not affected by the task blocking.
import tkinter as tk
import tkinter.ttk as ttk
import win32clipboard
import threading as thrd
import time
import os
from queue import Queue
def watchClip(top):
lastid = None
print("StartWatch")
while True:
time.sleep(0.01)
nowid = win32clipboard.GetClipboardSequenceNumber()
# print(nowid, lastid)
if not lastid or (lastid != nowid):
lastid = nowid
top.event_generate("<<clipUpdateEvent>>", when="tail")
def workButton(top, path, outQueue):
allcount = 0
print("StartSearch")
for root, dirs, files in os.walk(path):
allcount += len(files)
top.clipboard_clear()
top.clipboard_append(allcount)
outQueue.put_nowait(allcount)
# top.event_generate("<<searchFin>>", data={"result": allcount}, when="tail")
top.event_generate("<<searchFin>>", data=f"result={allcount}", when="tail")
def bind_event_data(widget, sequence, func, add=None):
def _substitute(*args):
def evt():
return None # simplest object with __dict__
try:
evt.data = eval(args[0])
except Exception:
evt.data = args[0]
evt.widget = widget
return (evt,)
funcid = widget._register(func, _substitute, needcleanup=1)
cmd = '{0}if {{"[{1} %d]" == "break"}} break\n'.format('+' if add else '', funcid)
widget.tk.call('bind', widget._w, sequence, cmd)
if __name__ == "__main__":
top = tk.Tk()
top.title("tktest")
top.geometry("300x200")
rsltQueue = Queue()
# top.bind("<<foo>>", vectrl)
print("begin")
lbl = tk.Label(top, text="clipboard", width=30, height=3)
lbl.pack()
lblrslt = tk.Label(top, text="SearchResult", width=40, height=3)
lblrslt.pack()
prb = ttk.Progressbar(top, length=100, mode="indeterminate")
prb.pack()
txt = tk.Entry(top, width=20)
txt.pack()
prb.start(interval=10)
t = thrd.Thread(target=watchClip, args=(top,), daemon=True)
t.start()
def searchPath():
t = thrd.Thread(target=workButton, args=(top, "c:", rsltQueue), daemon=True)
t.start()
bt2 = tk.Button(top, text="SearchPath", command=searchPath)
bt2.pack()
clipText = ""
def dealCUE(event):
global clipText
try:
clipText = top.clipboard_get()
except tk.TclError:
pass
lbl["text"] = clipText
def dealSF(event):
# lblrslt["text"] = f"allFileCount={rsltQueue.get()}"
# lblrslt["text"] = event.data["result"]
lblrslt["text"] = event.data
top.bind("<<clipUpdateEvent>>", dealCUE)
# top.bind("<<searchFin>>", dealSF)
bind_event_data(top, "<<searchFin>>", dealSF)
top.mainloop()
Python 3.7.2, os win10 1151, the test passed. (Continuous click on the button, open 12 worker threads, no problems found, UI thread is smooth)
If the code has an unexpected error, check tk*.dll in the python installation directory.
There is information that tk86t.dll supports multithreading, tk86.dll is not supported.
Thanks to #FabienAndre, #BryanOakley ,#stovfl and everyone in the discussion. You gave me the inspiration to solve this problem.
If you feel that this solution has some flaws, please let me know.

Certain exception occurs during Page Object Model implementation. What am I doing wrong?

I want to implement the principle of Page Object Model in my automation project in order to turn it into a real Framework.
The tested object is a device WEB GUI. This device GUI can be separated into frames. Each of the frame includes some elements. In order to represent the device GUI in POM (Page Object Model) I plan to construct a separate file (POM) to each of the frames in my GUI.
Only one of these frames is going to have a lot of methods, all the rest will mostly include elements (by the way I would like to know if it is right to implement the frames without methods according to the POM principle ?).
In the following example I started to characterize several of the frames and I have written a Test Case that will interact with them. My problem is that at a certain point in the Test Case script (Simple_Test.py) I possibly get into an exception and I don't know why. I have debugged Simple_Test.py and found out that whenever I reach to Pwr, OSNR = Main_Screen.Get_Rx_Pwr(browser) the next step would be execute_code(i, browser) and then the next step is the browser.quit() (under the except:).
Can somebody please help me to solve this issue ?
The following are the relevant scripts:
Simple_Test.py
from selenium import webdriver
from WEB_Pages.Login_POM import Login_Page
#from WEB_Pages.Main_Screen_POM.Main_Screen import Get_Rx_Pwr
from WEB_Pages.Main_Screen_POM import *
def main():
i = 0
while True:
i = i +1
profile = webdriver.FirefoxProfile()
profile.accept_untrusted_certs = True
browser = webdriver.Firefox(firefox_profile = profile)
browser.implicitly_wait(20) # Implicit wait
try:
execute_code(i, browser)
browser.quit()
if i == 2:
break
except:
browser.quit()
def execute_code(i, browser):
browser.get('http://10.0.1.131')
login = Login_Page(browser)
login.Login('admin', 'admin')
# Port = Device_Panel_Frame.Port_19
Pwr, OSNR = Main_Screen.Get_Rx_Pwr(browser)
# print (Port)
print (Pwr)
print (OSNR)
# print('The measured Uplink 1 Power is', Pwr)
# print('The measured Uplink 1 OSNR is', OSNR)
if __name__ == '__main__':
main()
Login_POM.py
from selenium import webdriver
class Login_Page(object):
'''
classdocs
'''
def __init__(self, driver):
'''
Constructor
'''
self.driver = driver
def Login(self, userName, pas):
user_name = self.driver.find_element_by_id('u_name_box')
user_name.send_keys(userName)
password = self.driver.find_element_by_id('u_pass_box')
password.send_keys(pas)
login_button = self.driver.find_element_by_id('login_but')
login_button.click()
Device_Panel_POM.py
from selenium import webdriver
class Device_Panel_Frame(object):
'''
classdocs
'''
def __init__(self, driver):
'''
Constructor
'''
self.driver = driver
self.driver.switch_to.default_content()
self.driver.switch_to.frame('box_menu')
self.driver.switch_to.frame('box_menu')
Port_19 = self.driver.find_element_by_id('Port-19')
Port_19.click()
Main_Screen_POM.py
from WEB_Pages.Device_Panel_POM import Device_Panel_Frame
class Main_Screen(object):
'''
classdocs
'''
def __init__(self, driver):
'''
Constructor
'''
self.driver = driver
def Get_Rx_Pwr(self):
Device_Panel_Frame.__init__(self, self.driver).Port_19
self.driver.switch_to.default_content()
# Show the Optic Module information TAB
self.driver.switch_to.frame('main_body')
CFP2_Info = self.driver.find_element_by_id('tab_XFP')
CFP2_Info.click()
# Collect the Rx Pwr from the CFP2 Info screen
self.driver.switch_to.frame('config_port') # Move to the inner frame that holds all the tables
#browser.find_element_by_class_name('table_round_corner')
Rx_Pwr = self.driver.find_element_by_xpath('html/body/form/div[1]/div/table/tbody/tr[2]/td[2]') # Take the Rx Pwr according to its Xpath
# print (Rx_Pwr.text) # print the Rx Pwr result to screen
RcvPwr = Rx_Pwr.text
# Collect the OSNR measurement from the CFP2 Info screen
OSNR = self.driver.find_element_by_xpath('html/body/form/div[1]/div/table/tbody/tr[4]/td[2]')
OSNR_Lvl = OSNR.text
return RcvPwr, OSNR_Lvl
By the way, the scripts: Device_Panel_POM, Login_POM and Main_Screen_POM are all under the same Package which is called WEB_Pages. Simple_Test is in a separate Package which is called Test_Cases.
I finally managed to understand the exception that occurred in my project. The issue was related to the fact that I didn't construct (I hope that I am using the right terminology) the Main_Screen_POM and instead I tried to activate a function within it.
Another mistake was that during the call to the function I exported a variable (browser) to the Get_Rx_Pwr function which doesn't get any arguments.
After fixing these issues I revealed another issue that related to the first line in the Get_Rx_Pwr function. The initialization there wasn't done right.

Pywinauto dont response

Im new in python and pywinauto, I need start a presentation in Chrome using pywinauto and Chrome_widgetWin_1, after I ran a program - Chrome started but just show a new tab, presentation didn't appear.
First part of program calls pdf a html presentations and add a path to Chrome,
second part is calling some Chrome widget for start a presentation but apparently it doesn't work.
I have no idea what can be the problem because I don't work with there up to now and on internet there is nothing helpful.
Can anyone has any experiences with that? I appreciate any kind of help, tnx :)
pdf = "\\CIT_presentation.pdf"
htmlpres = "file:///...template_cit2.html#1"
adobe = "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe"
chrome = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
import xml.etree.ElementTree as ET
from suds.client import Client
class Presentation:
def start(self):
from pywinauto import application
app = application.Application()
app.start_(chrome)
pwa_app = pywinauto.application.Application()
while True:
try:
w_handle = pywinauto.findwindows.find_windows(class_name='Chrome_WidgetWin_1')[0]
window = pwa_app.window_(handle=w_handle)
window.TypeKeys(htmlpres, with_spaces = True)
window.TypeKeys("~")
break
except:
pass
Probably you mixed 2 Application objects: app and pwa_app. app relates to started chrome.exe process, pwa_app is not connected to any process, it's just a "copy-paste" from SWAPY tool.
Just remove line pwa_app = pywinauto.application.Application() and replace all pwa_app objects with app ones.
[edit1] Just in case... You need 32-bit Python 2.7.
Trying to understand the question.. First let's make that code able to actually run, by :
import pywinauto
import time
import sys
htmlpres = "zcuba.dk/2014"
chrome = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
class Presentation:
def __init__(self):
pass
def start(self):
app = pywinauto.application.Application()
app.start_(chrome)
pwa_app = pywinauto.application.Application()
while True:
try:
w_handle = pywinauto.findwindows.find_windows(class_name='Chrome_WidgetWin_1')[0]
window = pwa_app.window_(handle=w_handle)
window.TypeKeys(htmlpres, with_spaces = True)
window.TypeKeys("~")
window.TypeKeys("{F11}")
break;
except:
e = sys.exc_info()[0]
print e
time.sleep(1)
p = Presentation()
p.start()
now it works here, I cannot find any errors... sorry
next debug version of the code, it looks less like your original version, and has a lot of output to help you pinpoint your problem!
import pywinauto
import time
import sys
htmlpres = "zcuba.dk/2014"
chrome = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
class Presentation:
def __init__(self):
pass
def start(self):
print "starting the pywinauto application object, by default construction"
pwa_app = pywinauto.application.Application()
print "start chrome, via pywinauto, without parameters, for later interaction"
pwa_app.start_(chrome)
print "now I'll attempt to communicate with the chrome instance"
while True:
try:
print "find the first windows application, that has an open window, with the class name 'Chrome_WidgetWin_1' (typically a chrome tab/window instance)"
w_handle = pywinauto.findwindows.find_windows(class_name='Chrome_WidgetWin_1')[0]
print "assigned a handle to the applications window:"
print "handle is: " + str(w_handle)
print "use the handle to create a window automation object"
window = pwa_app.window_(handle=w_handle)
print "window object created:"
print window
print "Now, attempt to simulate keyboard, and write the address in the chrome window (wherever focus is - we assume it is in the address bar - but some extensions can change this behaviour)"
window.TypeKeys(htmlpres, with_spaces = True)
print "pressing enter to start the search for the address entered"
window.TypeKeys("{ENTER}")
print "pressing F11 to go for fullscreen - it is a presentation ;)"
window.TypeKeys("{F11}")
print "yay, we are done :)"
break;
except:
print "Oh, no, an Exception, (something went wrong):"
e = sys.exc_info()[0]
print e
time.sleep(1)
print "will now retry_________________________________________"
print "build presentation object"
p = Presentation()
print "start presentation"
p.start()
Vasily --- yes, now it print a some errors
<type 'exceptions.TypeError'>
File "C:/.../Program.py", line 23, in start
window = app.window_(handle=w_handle)
File "C:\Python27\lib\site-packages\pywinauto\application.py", line 400, in window_
**kwargs)
File "C:\Python27\lib\site-packages\pywinauto\application.py", line 290, in _wait_for_function_success
return func(*args, ** kwargs)
File "C:\Python27\lib\site-packages\pywinauto\findwindows.py", line 60, in find_window
windows = find_windows(**kwargs)
TypeError: find_windows() got an unexpected keyword argument 'handle'

Categories

Resources