PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label selenium-webdriver. Show all posts
Showing posts with label selenium-webdriver. Show all posts

Thursday, September 15, 2022

[FIXED] How to handle Firefox print dialog box in Selenium

 September 15, 2022     printing, python, selenium, selenium-webdriver     No comments   

Issue

I have the following code:

from selenium.webdriver import Firefox
from selenium.webdriver.common.keys import Keys
url = 'https://finance.yahoo.com/'
driver_path = 'geckodriver.exe'

browser = Firefox(executable_path = driver_path)
browser.get(url)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
profile.set_preference("browser.helperApps.neverAsk.openFile", "application/pdf")
search_field_id = 'yfin-usr-qry'

element_search_field = browser.find_element_by_id(search_field_id)
element_search_field.clear()
element_search_field.send_keys('TSLA')
element_search_field.send_keys(Keys.ENTER)
from selenium.webdriver import ActionChains
action_chains = ActionChains(browser)
action_chains.key_down(Keys.CONTROL).send_keys('V').key_up(Keys.CONTROL).perform()
xpath_string = '/html/body/div[1]/div/div/div[1]/div/div[2]/div/div/div[6]/div/div/section/div/ul/li[2]/a/span'
element = browser.find_element_by_xpath(xpath_string)
action_chains.move_to_element(element).click().perform()
browser.execute_script('window.print();')

A print dialog box pops up for Firefox. I was wondering how can i accept it. Is there a way to bypass this dialog box and directly print since this is not a system dialog box but Firefox's.

enter image description here

Edit: My full updated code as per input from @Prophet

from selenium.webdriver import Firefox
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import Select
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
import time
from fake_useragent import UserAgent
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
ua = UserAgent()
userAgent = ua.random

url = 'https://finance.yahoo.com/'
driver_path = 'geckodriver.exe'

profile = FirefoxProfile('C:\\Users\\\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\tp3cz5dm.default-release')
profile.set_preference("general.useragent.override", userAgent)

browser = Firefox(executable_path = driver_path)
browser.get(url)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
profile.set_preference("browser.helperApps.neverAsk.openFile", "application/pdf")
search_field_id = 'yfin-usr-qry'

element_search_field = browser.find_element_by_id(search_field_id)
element_search_field.clear()
element_search_field.send_keys('TSLA')
element_search_field.send_keys(Keys.ENTER)
from selenium.webdriver import ActionChains
action_chains = ActionChains(browser)
action_chains.key_down(Keys.CONTROL).send_keys('V').key_up(Keys.CONTROL).perform()
# xpath_string = '/html/body/div[1]/div/div/div[1]/div/div[2]/div/div/div[6]/div/div/section/div/ul/li[2]/a/span'
# element = browser.find_element_by_xpath(xpath_string)
# action_chains.move_to_element(element).click().perform()
browser.execute_script('window.print();')

browser.switch_to.window(browser.window_handles[-1])
time.sleep(0.5)
actionButton = browser.execute_script(
"return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-button-strip').shadowRoot.querySelector('.action-button')")
cancelButton.click()
# switch back to main window
browser.switch_to.window(driver.window_handles[0])

When i run this i am getting error:

JavascriptException: TypeError: document.querySelector(...) is null


Solution

Both the solutions below are designed NOT to launch the print dialog. These solutions will either print the active webpage to your local printer or to a PDF file without having to deal with the dialog.

UPDATED POST 08-19-2021


I wanted to save the output to PDF vs printing to paper. I was shocked how hard it was to print to a PDF using the geckodriver and selenium. With the 'chromedriver' you can call the function 'execute_cdp_cmd' and pass Page.printToPDF. The geckodriver doesn't have 'execute_cdp_cmd'.

When I looked through Stack Overflow for inspiration, I discover multiple open question on printing pdf using the geckodriver with selenium. After seeing that this was a problem, I looked through the issues in selenium and the bug reports for mozilla. Again this was a problem that others had.

Some of the bug reports mentioned that certain switches used in the print process no longer worked.

profile.set_preference("print.print_to_file", True)
profile.set_preference("print.print_to_filename", "/tmp/file.pdf")

I decided to look at the source code for mozilla gecko-dev for a potential solution. After hours of research I found that the switches above were replaced with new ones and that another printer variable had also been replaced. After some testing, I was able to get your webpage to save as PDF.

The code below will print a webpage to a PDF with all the links enabled. I would recommend adding some error handling to the code. One part of the code that I need to improve on the filename part. You should be able to add a function that will rename the file, which would allow you to print as many files as you want in a single session.

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.options import FirefoxProfile

firefox_options = Options()
firefox_options.add_argument("--disable-infobars")
firefox_options.add_argument("--disable-extensions")
firefox_options.add_argument("--disable-popup-blocking")

profile_options = FirefoxProfile()
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11.5; rv:90.0) Gecko/20100101 Firefox/90.0'
profile_options.set_preference('profile_options = FirefoxProfile()', user_agent)
profile_options.set_preference("print_printer", "Mozilla Save to PDF")
profile_options.set_preference("print.always_print_silent", True)
profile_options.set_preference("print.show_print_progress", False)
profile_options.set_preference('print.save_as_pdf.links.enabled', True)
profile_options.set_preference("print.printer_Mozilla_Save_to_PDF.print_to_file", True)

# set your own file path
profile_options.set_preference('print.printer_Mozilla_Save_to_PDF.print_to_filename',
                               "tmp/testprint.pdf")


driver = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver', options=firefox_options,
                           firefox_profile=profile_options)


URL = 'https://finance.yahoo.com/'


driver.get(URL)

sleep(10)

search_field_id = 'yfin-usr-qry'

element_search_field = driver.find_element_by_id(search_field_id)
element_search_field.clear()
element_search_field.send_keys('TSLA')
element_search_field.send_keys(Keys.ENTER)

sleep(10)

driver.execute_script("window.print()")

sleep(20)

driver.quit()

ORIGINAL POST 08-18-2021


I decided to look at your issue, because I'm interested in selenium functionality.

I looked through the source code of the geckodriver and found printUtils.js, which provides details on the switches used in the print process, such as these:

firefox_options.set_preference("print.always_print_silent", True)
firefox_options.set_preference("print.show_print_progress", False)

After removing some of your code and adding some, I was able to print to my HP printer with the code below without dealing with a print dialog box:

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.options import FirefoxProfile

firefox_options = Options()
firefox_options.add_argument("--disable-infobars")
firefox_options.add_argument("--disable-extensions")
firefox_options.add_argument("--disable-popup-blocking")

profile_options = FirefoxProfile()
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11.5; rv:90.0) Gecko/20100101 Firefox/90.0'
firefox_options.set_preference('profile_options = FirefoxProfile()', user_agent)
firefox_options.set_preference("print.always_print_silent", True)
firefox_options.set_preference("print.show_print_progress", False)
firefox_options.set_preference("pdfjs.disabled", True)

driver = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver', options=firefox_options)

URL = 'https://finance.yahoo.com/'

driver.get(URL)

sleep(10)

search_field_id = 'yfin-usr-qry'

element_search_field = driver.find_element_by_id(search_field_id)
element_search_field.clear()
element_search_field.send_keys('TSLA')
element_search_field.send_keys(Keys.ENTER)

sleep(10)
driver.execute_script("window.print()")
----------------------------------------
My system information
----------------------------------------
Platform:    Apple
OS:          10.15.7
Python:      3.9
Selenium:    3.141
Firefox:     90.0.2
Geckodriver: 0.29.0

----------------------------------------


Answered By - Life is complex
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 31, 2022

[FIXED] How to check if Open File dialog has been open after pressing a button in a Chrome Browser tab on Python?

 July 31, 2022     file-upload, fileopendialog, python-3.x, selenium, selenium-webdriver     No comments   

Issue

I'm trying to automate a process within the OpenSea Create page after having logged in with Metamask, and so far, I have managed to develop a simple program that chooses a particular image file using a path which passes to the Open File dialog "implicitly", here's the code:

import pyautogui
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

def wait_xpath(code): #function to wait for the xpath of an element to be located
    WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, code)))


opt = Options() #the variable that will store the selenium options
opt.add_experimental_option("debuggerAddress", "localhost:9222") #this allows bulk-dozer to take control of your Chrome Browser in DevTools mode.
s = Service(r'C:\Users\ResetStoreX\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe') #Use the chrome driver located at the corresponding path
driver = webdriver.Chrome(service=s, options=opt) #execute the chromedriver.exe with the previous conditions

nft_folder_path = r'C:\Users\ResetStoreX\Pictures\Cryptobote\Cryptobote NFTs\Crypto Cangrejos\SANDwich\Crabs'
start_number = 3


if driver.current_url == 'https://opensea.io/asset/create':
    print('all right')
    print('')
    print(driver.current_window_handle)
    print(driver.window_handles)
    print(driver.title)
    print('')
    nft_to_be_selected = nft_folder_path+"\\"+str(start_number)+".png"
    wait_xpath('//*[@id="main"]/div/div/section/div/form/div[1]/div/div[2]')
    imageUpload = driver.find_element(By.XPATH, '//*[@id="main"]/div/div/section/div/form/div[1]/div/div[2]').click() #click on the upload image button
    print(driver.current_window_handle)
    print(driver.window_handles)
    time.sleep(2)
    pyautogui.write(nft_to_be_selected) 
    pyautogui.press('enter', presses = 2)

Output:

preview0

After checking the URL, the program clicks on the corresponding button to upload a file

preview1

Then it waits 2 seconds before pasting the image path into the Name textbox, for then pressing Enter

preview2

So the file ends up being correctly uploaded to this page.

The thing is, the program above works because the following conditions are met before execution:

  1. The current window open is the Chrome Browser tab (instead of the Python program itself, i.e. Spyder environment in my case)
  2. After clicking the button to upload a file, the Name textbox is selected by default, regardless the current path it opens with.

So, I'm kind of perfectionist, and I would like to know if there's a method (using Selenium or other Python module) to check if there's an Open File dialog open before doing the rest of the work.

I tried print(driver.window_handles) right after clicking that button, but Selenium did not recognize the Open File dialog as another Chrome Window, it just printed the tab ID of this page, so it seems to me that Selenium can't do what I want, but I'm not sure, so I would like to hear what other methods could be used in this case.

PS: I had to do this process this way because send_keys() method did not work in this page


Solution

The dialog you are trying to interact with is a native OS dialog, it's not a kind of browser handler / dialog / tab etc. So Selenium can not indicate it and can not handle it. There are several approaches to work with such OS native dialogs. I do not want to copy - paste existing solutions. You can try for example this solution. It is highly detailed and looks good.



Answered By - Prophet
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to select many files using Windows file explorer with selenium webdriver

 July 31, 2022     file-upload, java, selenium, selenium-webdriver, webdriver     No comments   

Issue

I am automating a UI test where selecting file to upload is involved, I was able to automate the file selection using this solution.

WebElement filepath=driver.findElement(By.id("fileUploadId"));
filepath.sendKeys("C:\\TextFile.txt");

My issue is that I need to select many files to upload, is there a special format I should follow in the path I am sending? because I tried space-separated paths and it didn't work.


Solution

To upload multiple files you can construct the character string adding all the absolute path of the files seperated by \n as follows:

WebElement filepath = driver.findElement(By.id("fileUploadId"));
filepath.sendKeys("C:/TextFile1.txt \n C:/TextFile2.txt \n C:/TextFile3.txt");

References

You can find a couple of relevant detailed documentations in:

  • How to upload multiple files using SendKeys Selenium
  • How to upload multiple files to a website using Python and Selenium?


Answered By - undetected Selenium
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, April 15, 2022

[FIXED] How to click on the reCAPTCHA using Selenium and Java

 April 15, 2022     iframe, recaptcha, selenium, selenium-webdriver, webdriverwait     No comments   

Issue

Why am I getting errors when trying to get the driver to click on the reCAPTCHA button?

This is the site where I am trying to get it to work: https://rsps100.com/vote/760/

This is my current code so far:

WebElement iframeSwitch = driver.findElement(By.xpath("/html/body/div[1]/div/div[1]/div/div/div[2]/div/form/div/div/div/div/iframe"));
driver.switchTo().frame(iframeSwitch);
driver.findElement(By.cssSelector("div[class=recaptcha-checkbox-checkmark]")).click();

Solution

To invoke click() on the reCaptcha checkbox as the element is within an <iframe> you need to:

  • Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt.
  • Induce WebDriverWait for the desired elementToBeClickable.
  • You can use the following solution:

    • Code Block:

      public class ReCaptcha_click {
      
          public static void main(String[] args) {
      
              System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
              ChromeOptions options = new ChromeOptions();
              options.addArguments("start-maximized");
              options.addArguments("disable-infobars");
              options.addArguments("--disable-extensions");
              WebDriver driver = new ChromeDriver(options);
              driver.get("https://rsps100.com/vote/760");
              new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[starts-with(@name, 'a-') and starts-with(@src, 'https://www.google.com/recaptcha')]")));
              new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.recaptcha-checkbox-checkmark"))).click();
          }
      }
      
  • Browser Snapshot:

    reCaptcha



Answered By - undetected Selenium
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I select a html element no matter what frame it is in in selenium?

 April 15, 2022     html, iframe, python, selenium, selenium-webdriver     No comments   

Issue

I am trying to select an element which resides inside an iframe and probably in other iframes.

Is it somehow possible to select an element within some (sub-)iframe in (python)selenium without selecting the iframes before? Is there a way to 'loop' over every iframe somehow and to check where to find my element...?

And how to do that in the case elements and html stuff and iframes might just about being loaded...?


Solution

No, it is not possible to interact with any WebElement within an <iframe> through Selenium without switching to the respective iframe.

Reason :

When a page is loaded, Selenium's focus by default remains on the Top Window. The Top Window contains the other <iframes> and the framesets. So when we need to interact with a WebElement which is within an iframe we have to switch to the respective <iframe> through one of the below-mentioned methods :


Frame Switching Methods :

We can switch over to frames by 3 ways.

By Frame Name :

Name attribute of iframe through which we can switch to it.

Example:

driver.switch_to.frame("iframe_name")

By Frame ID :

ID attribute of iframe through which we can switch to it.

Example:

driver.switch_to.frame("iframe_id")

By Frame Index :

Suppose if there are 10 frames in the page, we can switch to the iframe by using the index.

Example:

driver.switch_to.frame(0)
driver.switch_to.frame(1)

Switching back to the Main Frame :

We can switch back to the main frame by using default_content() or parent_frame()

Example:

driver.switch_to.default_content()
driver.switch_to.parent_frame()

A Better Approach to Switch Frames:

A better way to switch frames will be to induce WebDriverWait for the availability of the intended frame with expected_conditions set to frame_to_be_available_and_switch_to_it as follows :

  • Through Frame ID:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
    
  • Through Frame Name:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"name_of_iframe")))
    
  • Through Frame Xpath:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"xpath_of_iframe")))
    
  • Through Frame CSS:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"css_of_iframe")))
    

Reference

You can find a relevant detailed discussion in:

  • Ways to deal with #document under iframe


Answered By - undetected Selenium
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to move Slider in an IFRAME that doesn't have a name/id?

 April 15, 2022     iframe, java, selenium-webdriver     No comments   

Issue

enter image description here I am unable to move the slider in an IFRAME section: https://jqueryui.com/slider/

The IFRAME doesn't have a name or id on this page.

Code:

public class MovingSlider {
    public static void main(String[] args) 
    {
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
        driver.get("https://jqueryui.com/slider/");
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        driver.switchTo().frame(1);
        WebElement slider = driver.findElement(By.xpath("//div[@id = 'slider']/span"));
        new Actions(driver).dragAndDropBy(slider, 400,0).click();
    }
}

Solution

The issue is dom contains only one frame whose index is "0" and you tried to switch to index "1" frame which actually didn't exist.

Following is the code snippet that works for you.

WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
driver.get("https://jqueryui.com/slider/");
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
Integer size = driver.findElements(By.tagName("iframe")).size();
System.out.println("Total iFrame is " + size);
driver.switchTo().frame(0);
WebElement slider = driver.findElement(By.xpath("//div[@id = 'slider']/span"));
// WebElement slider = driver.findElement(By.cssSelector("#slider > span"));
new Actions(driver).dragAndDropBy(slider, 400, 0).build().perform();


Answered By - Muhammad Farooq
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, February 10, 2022

[FIXED] yii selenium radio button is checked?

 February 10, 2022     php, selenium-webdriver, yii     No comments   

Issue

I am trying to tell which of two radio buttons is checked. I have no problem testing the values of text inputs and dropdowns, but I just can't seem to figure out how to test whether or not a radio button is checked.

I am using the selenium test driver with yii (not yii2) in php. Does anybody know how to do this?

For example, how would I determine which of the following radio buttons is checked?

<input id="gender_0" value="M" type="radio" name="gender">
<input id="gender_1" value="F" type="radio" name="gender">

The way that I am trying to do it now is like this

$this->assertNotNull('#gender_'.($gender == 'M' ? 0 : 1).':checked');
$this->assertNull('#gender_'.($gender == 'M' ? 1 : 0).':checked');

The following works in a web browser's console, but I don't know how to do it in php with yii's Selenium web driver.

console.assert(document.querySelector('#gender_0:checked') != null);

Solution

This solved the problem for me:

$this->assertChecked('id=gender_'.($gender == 'M' ? 0 : 1));
$this->assertNotChecked('id=gender_'.($gender == 'M' ? 1 : 0));

I used assertChecked and assertNotChecked instead of assertNotNull and assertNull, changed the '#' to 'id=', and removed ':checked'.



Answered By - hutch90
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing