Can't take screenshot using selenium - python

Just met a strange problem while running selenium to take the screenshot of web page, below is part of my code:
url = "http://acme.com/licensemaker/licensemaker.cgi?state=California"
driver = webdriver.PhantomJS()
driver.maximize_window()
elem = driver.get(url)
elem = \
driver.find_element_by_xpath
('/html/body/form/center/div/table/tbody/tr[2]/td/input[2]')
elem.send_keys(comb)
driver.find_element_by_xpath
('/html/body/form/center/div/table/tbody/tr[2]/td/input[3]').click()
driver.save_screenshot('../screenshots/1.png')
print('ok')
img = driver.find_element_by_xpath('/html/body/center[1]/div/a/img')
location = img.location
size = img.size
print(size)
I try both PhantomJS and Safari driver neither can they save the screenshot, but I can get the output of both 'ok' and the value of 'location'.
I don't understand why I can't save the screenshot.
Saving the file via absolute path failed but only name worked. I use the same version of Selenium last year it worked with relative path, what happened?
The result of save_screenshot() is True.
OS: macOS Sierra 10.12.5
Interpreter: 2.7.12(/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7)
plus, I'm using Pyenv, and my Pyenv global is 'system'.

You have to consider the fact that, while invoking save_screenshot() you have to mention the full path you wish to save your screenshot to. This should end with a .png extension. As per your case, you may consider to create a directory by the name "screenshots" within your project space through your IDE or manually. In your code mention the path as:
driver.save_screenshot('/screenshots/123.png')

You can use below function for relative path as absolute path is not a good idea to add in script
Import
import sys, os
Use code as below :
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
screenshotpath = os.path.join(os.path.sep, ROOT_DIR,'Screenshots'+ os.sep)
driver.get_screenshot_as_file(screenshotpath+"testPngFunction.png")
make sure you create folder where .py file is present.
os.path.join also prevent you to run your script in cross platform like : unix and windows. It will generate path seprator as per OS in runtime. It is similer like File.separtor in java

Related

how to print current wallpaper path in windows 10 using python?

python program to print the current wallpaper path as output
i have tried this code but its not working
pip install py-wallpaper
from wallpaper import set_wallpaper, get_wallpaper
print(get_wallpaper())
set_wallpaper("location/to/image.jpg")
This shows the error that win-wallpaper is not regognised as internal or external command
how to print the path of current wallpaper path in windows using python?
The library have a bug. To overcome follow these steps.
1. Open wallpaper library directory and create a file name win-wallpaper.py.
2. Add following code into newly create module .
import ctypes,win32con
def getWallpaper():
ubuf = ctypes.create_unicode_buffer(512)
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_GETDESKWALLPAPER,len(ubuf),ubuf,0)
return ubuf.value
print(getWallpaper())
3. Then use pyinstaller to convert py to exe file.
Note: Don't use cmd for compile purpose .
pyinstaller --onefile -w 'win-wallpaper.py'
4. From dist folder take win-wallpaper.exe file to main directory.
Now, it is good to go.
But one thing you should not here, this library still not contain proper implementation of set_wallpaper(path) function. This contain lots of bug so please use last code stuff.
If you don't want to use this library then use this code.
import ctypes,win32con
def getWallpaper():
ubuf = ctypes.create_unicode_buffer(512)
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_GETDESKWALLPAPER,len(ubuf),ubuf,0)
return ubuf.value
def setWallpaper(path):
changed = win32con.SPIF_UPDATEINIFILE | win32con.SPIF_SENDCHANGE
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_SETDESKWALLPAPER,0,path,changed)

How to select pictures in dialogue box using Selenium (mac) [duplicate]

How to upload a picture on a web application with the selenium testing tool? I am using python.
I tried many things, but nothing worked.
What I'm doing is this (make sure drv is an instance of webdriver):
drv.find_element_by_id("IdOfInputTypeFile").send_keys(os.getcwd()+"/image.png")
and then find your submit button and click it.
A very easy way to control components like windows file selector (or just your OS in general) is by using pyautogui. You can install pyautogui through pip
import pyautogui
... # set the webdriver etc.
...
...
element_present = EC.presence_of_element_located((By.XPATH, "//button[#title='Open file selector']")) # Example xpath
WebDriverWait(self.driver, 10).until(element_present).click() # This opens the windows file selector
pyautogui.write('C:/path_to_file')
pyautogui.press('enter')
I am using fine-uploader, running selenium tests with pytest and this worked for me:
elm = driver.find_element_by_xpath("//input[#type='file']")
elm.send_keys(os.getcwd() + "/tests/sample_files/Figure1.tif")
No form submission or Enter key is needed in my case.
I added an answer for anyone looking to use deal with the annoying msofiledialogs. This is working off of saravanan's proposed solution, but more fleshed out for Python.
I had a similar problem with a script I'm working on for a company on the side. I'm attempting to upload documents for a company's clients, but due to the way their site worked, I could not utilize send_keys to directly send the path, so I had to rely on msofiledialog.
You only need to install AutoIt
https://pypi.python.org/pypi/PyAutoIt/0.3 or just "pip install -U pyautoit" through the cmd screen
type "import autoit" on your script page
Type the following before the file dialog pops up in your script:
autoit.win_active("Open")
autoit.control_send("Open","Edit1",r"C:\Users\uu\Desktop\TestUpload.txt")
autoit.control_send("Open","Edit1","{ENTER}")
It will look for the open file dialog window and fill it out and press enter.
"Open" is the title of my file dialog screen. Put the title of yours in place of "Open". There are more creative ways to utilize AutoIt's functions, but this is an easy, straightforward way for beginners.
Edit: DO NOT. DO NOT use control_send on most things if you can avoid it. It has a well-known issue of sending erroneous text. In my case, the colon in my file path was being turned into a semi colon. If you need to send input keys, it should be fine, however if you need to send text, use control_set_text. It has the same syntax.
autoit.control_set_text("Open","Edit1",r"C:\Users\uu\Desktop\TestUpload.txt")
All these approach wont work with modern image uploaders in olx !!!
Alternative approach (only for windows )
1. Automation of windows can be done using Autoit
2. Install Autoit and SciTe Script editor
3. Autoit code :(imageupload.au3)
WinActivate("File Upload"); for chrome use "open" that is the name of the window that pops
send("D:\images\image1.png"); path of the file
Send("{ENTER}")
4. compile it to get an .exe file(imageupload.exe)
5. Now from python call the .exe file like
import os
import os.system('C:\images\imageupload.exe') #path of the .exe file
Upload input control opens a native dialog (it is done by browser) so clicking on the control or browse button via Selenium will just pop the dialog and the test will hang.
The workaround is to set the value of the upload input via JavaScript (in Java it is done via JavascriptExecutor) and then submit the form.
See this question for sample in C#, I am sure there's also a way to call JavaScript in Python but I never used Selenium Python bindings
Here is the code that i used:
Imagepath = "C:\User\Desktop\image.png"
driver.find_element_by_xpath('//html/body/input').send_keys(Imagepath)
driver.find_element_by_xpath('//html/body/button').click()
I accept the Answer by karloskar. Note It is not working for FireFox (59). And it is works with Chrome Driver only.
import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.Sendkeys("C:\text.txt")
shell.Sendkeys("~")
Will resolve the issue
You can easily add this one line of code to solve the problem:
driver.find_element_by_xpath("your fullpath").send_keys("C://1.png(your file root")
But pay attention, sometimes maybe you put a wrong xpath in first field. follow below steps for reach to rightful xpath:
open the inspect and click exactly on the box which you want to
upload the file.
right click on the html code and select xpath full address from copy
sub menu.
paste the root in xpath field in the code.
full code to achieve file upload using autoit tool.
u can just copy paste this and u can run, it will work since it is a acti-time demo.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import os
def fileUploading():
driver = webdriver.Firefox()
driver.implicitly_wait(20)
wait = WebDriverWait(driver, 10)
driver.get("https://demo.actitime.com/login.do");
driver.find_element(By.ID,"username").send_keys("admin")
driver.find_element(By.NAME, "pwd").send_keys("manager")
driver.find_element(By.XPATH, "//div[.='Login ']").click()
wait.until(ec.element_to_be_clickable((By.XPATH, "(//div[#class='popup_menu_icon'])[3]")))
driver.find_element(By.XPATH, "(//div[#class='popup_menu_icon'])[3]").click()
wait.until(ec.element_to_be_clickable((By.XPATH, "//a[contains(text(),'Contact actiTIME Support')]")))
driver.find_element(By.XPATH, "//a[contains(text(),'Contact actiTIME Support')]").click()
wait.until(ec.element_to_be_clickable((By.XPATH,"//div[#class='dz-default dz-message']")))
driver.find_element(By.XPATH,"//div[#class='dz-default dz-message']").click()
os.system("C:\\Users\\mallikar\\Desktop\\screenUpload.exe")
time.sleep(2000)
fileUploading()
below is the content of autoit code:
WinWaitActive("File Upload")
Send("D:\SoftwareTestingMaterial\UploadFile.txt")
Send("{ENTER}")
download autoIt and autoIt SCITE editor tool.
once done install autoit and the open the scite editor and paste the above code and save it with .au3 extension and once saved, right click on the file and select complile script(x64), now .exe file is created.
now use the below code:
os.system("C:\\Users\\mallikar\\Desktop\\screenUpload.exe")
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.example.org")
def upload_file():
upload_file = driver.find_element_by_id("paste here id of file which
is
enter code here`shown in html code...")
upload_file.send_keys("copy the path of file from your pc with name and
paste here...")
if toast message is disappeared within seconds you can use Chropath extension in chrome to find its xpath
This is a pure python code.
Instead of using control_send, use control_set_text to resolve inconsistencies present in the string sent to the window. See this link for reference: https://www.autoitscript.com/forum/topic/85929-incorrect-string-being-sent-via-controlsend/
import autoit
autoit.win_wait_active("Open")
autoit.control_set_text("Open", "Edit1", imgPath)
autoit.send("{ENTER}")
Use PyAutoGui if sendkeys function is not working on buttons.
sample code:
import pyautogui
driver.find_element_by_xpath("Enter Xpath of File upload button").click()
time.sleep(4) #waiting for window popup to open
pyautogui.write(r"C:\Users\AmarKumar\FilesForUploading\image.jpg") #path of File
pyautogui.press('enter')
I have used below script format to upload the images. This may help you.
Imagepath=os.path.abspath('.\\folder1\\subfolder2\file1.jpg')
driver.find_element_by_id("Id of the element").clear()
driver.find_element_by_id("Id of the element").send_keys(Imagepath)
if you do not have ID of the object ,then you can use xpath or css selector accordingly.
Using splinter :
browser.attach_file('file_chooser_id',fully_qualified_file_path)
If you are using service you will get an exception
service = Service('driver_path')
service.start()
driver = webdriver.Remote(service.service_url)
choose_image = driver.find_element(By.ID, 'id')
choose_image.send_keys(os.getcwd()+'/image.jpg')
Exception :
selenium.common.exceptions.WebDriverException: Message: unknown command: unknown command: session/$sessionId/se/file
Working code (suggestion - use id of the element instead of other)
driver=webdriver.Chrome(executable_path=driver_path)
choose_image=driver.find_element(By.ID, 'id')
choose_image.send_keys(os.path.join(os.getcwd(), 'image.jpg'))
In case you want to upload multiple pictures, you can alter the single image answer as follows:
images = ["/path/to/image1.png", "/path/to/image2.png","/path/to/image3.png"]
drv.find_element_by_id("IdOfInputTypeFile").send_keys("\n".join(images))
Note that the input form should have the multiple attribute set to True.
I post a solution that i consider best. it is a modification on solution by #sherlock (see my comment on that post)
import autoit
autoit.win_wait_active("Open")
autoit.control_set_text("Open", "Edit1", imgPath)
autoit.control_click("Open", "Button1")
Install these three
sudo apt-get install python3-tk python3-dev
pip install tk
pip install PyAutoGUI
use these two line of code.
pyautogui.write('/home/image.jpg')
pyautogui.press('enter')

Screenshot of a website with Python (Windows)

How to take a screenshot of a website with Python, Windows environment ?
Remarks :
The question of taking a screenshot of a website with Python has been highly discussed here but most of the solutions only work for Mac like webkit2png (see the discussion here about portability and also this answer) or Linux
The only half-working solution I've found is :
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://www.example.com')
browser.save_screenshot('test.png')
it works 50% of the time, but when doing it for 100 pages, in a loop, it always stops / is stuck / after 10 or 15 or 25 pages. Even if I time.sleep(...), etc.
I created a library called pywebcapture that wraps selenium that will do just that:
pip install pywebcapture
Once you install with pip, you can do the following to easily get full size screenshots:
# import modules
from pywebcapture import loader, driver
# load csv with urls
csv_file = loader.CSVLoader("csv_file_with_urls.csv", has_header_bool, url_column, optional_filename_column)
uri_dict = csv_file.get_uri_dict()
# create instance of the driver and run
d = driver.Driver("path/to/webdriver/", output_filepath, delay, uri_dict)
d.run()
Enjoy!
https://pypi.org/project/pywebcapture/

Python3.1 - Open Opera

I have no idea why this won't work....I'm trying to open opera but it says cannot find runnable browser.
op = webbrowser.get('C:\\Program Files\\Opera\\opera.exe')
op.open_new_tab('http://www.stackoverflow.com')
op.open_new_tab('http://www.stackoverflow.com')
The name parameter should just be 'opera':
op = webbrowser.get('opera')
Make sure you have installed Opera on your computer, and that the executable opera.exe is in the path.
>>> import webbrowser
>>> webbrowser.get('opera')
<webbrowser.BackgroundBrowser object at 0x02095490>
See the table of allowed values for the name parameter in the documentation.
If you want to specify the exact path to the executable (which by the way is a bad idea if you want your application to be portable) then you can specify the command line as follows:
op = webbrowser.get(r'C:\\Program Files\\Opera\\opera.exe %s')
As far as I know, you cannot provide a specific filepath for the browser you want to associate with the webbrowser object. You need to just provide one of a few built-in names. The one you want here is "opera" - see http://docs.python.org/py3k/library/webbrowser.html for details.
You should try to set the browser path to BROWSER environment variable.
Here's how to do it in Windows (which you are apparently using):
http://vlaurie.com/computers2/Articles/environment.htm

How to find the real user home directory using python?

I see that if we change the HOME (linux) or USERPROFILE (windows) environmental variable and run a python script, it returns the new value as the user home when I try
os.environ['HOME']
os.exp
Is there any way to find the real user home directory without relying on the environmental variable?
edit:
Here is a way to find userhome in windows by reading in the registry,
http://mail.python.org/pipermail/python-win32/2008-January/006677.html
edit:
One way to find windows home using pywin32,
from win32com.shell import shell,shellcon
home = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, None, 0)
I think os.path.expanduser(path) could be helpful.
On Unix and Windows, return the argument with an initial component of ~ or ~user replaced by that user‘s home directory.
On Unix, an initial ~ is replaced by the environment variable HOME if it is set; otherwise the current user’s home directory is looked up in the password directory through the built-in module pwd. An initial ~user is looked up directly in the password directory.
On Windows, HOME and USERPROFILE will be used if set, otherwise a combination of HOMEPATH and HOMEDRIVE will be used. An initial ~user is handled by stripping the last directory component from the created user path derived above.
If the expansion fails or if the path does not begin with a tilde, the path is returned unchanged.
So you could just do:
os.path.expanduser('~user')
from pathlib import Path
str(Path.home())
works in Python 3.5 and above. Path.home() returns a Path object providing an API I find very useful.
I think os.path.expanduser(path) is the best answer to your question, but there's an alternative that may be worth mentioning in the Unix world: the pwd package. e.g.
import os, pwd
pwd.getpwuid(os.getuid()).pw_dir
For windows;
import os
homepath = os.path.expanduser(os.getenv('USERPROFILE'))
will give you a handle to current user's home directory and
filepath = os.path.expanduser(os.getenv('USERPROFILE'))+'\\Documents\\myfile.txt'
will give you a handle to below file;
C:\Users\urUserName\Documents\myfile.txt
home_folder = os.getenv('HOME')
This should work on Windows and Mac OS too, works well on Linux.
Really, a change in environment variable indicates that the home must be changed. So every program/script should have the new home in context; also the consequences are up to the person who changed it.
I would still stick with
home = os.getenv('USERPROFILE') or os.getenv('HOME')
what exactly is required?
I realize that this is an old question that has been answered but I thought I would add my two cents. The accepted answer was not working for me. I needed to find the user directory and I wanted it to work with and without sudo. In Linux, my user directory is "/home/someuser" but my root directory is "/root/". However, on my Mac, the user directory is "/Users/someuser". Here is what I ended up doing:
_USERNAME = os.getenv("SUDO_USER") or os.getenv("USER")
_HOME = os.path.expanduser('~'+_USERNAME)
This worked both with and without sudo on Mac and Linux.
get (translated) user folder names on Linux:
from gi.repository import GLib
docs = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)
desktop = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)
pics = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)
videos = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)
music = GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)
downloads = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
public = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE)
templates = GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES)
print(docs)
print(desktop)
print(pics)
print(videos)
print(music)
print(downloads)
print(public)
print(templates)
On Linux and other UNIXoids you can always take a peek in /etc/passwd. The home directory is the sixth colon-separated field in there. No idea on how to do better than the environment variable on Windows though. There'll be a system call for it, but if it's available from Python, ...

Categories

Resources