Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python with Selenium: Is it possible to refresh frame instead of the whole page?

If selenium cannot refresh frame, I'm working on a web page which has nested frames. The structure is basically: webpage -> frame A -> frame B -> frame C I need to refresh frame C constantly. I'm wondering if selenium can achieve this. As far as I can test, the refresh() function refreshes the whole page.

The annoying part is that the only button that can refresh frame C resides on frame B, so currently I have to do the following loop:

while True:
    browser.switch_to_default_content()
    WebDriverWait(browser, 10).until(EC.frame_to_be_available_and_switch_to_it(("frame A")))
    WebDriverWait(browser, 10).until(EC.frame_to_be_available_and_switch_to_it(("frame B")))
    browser.find_element_by_css_selector("refresh_button").click()
    WebDriverWait(browser, 10).until(EC.frame_to_be_available_and_switch_to_it(("frame C")))

If selenium cannot refresh frame, I'm wondering if there is a better way to switch between frame B and C? I really don't want to go to default content and frame A again and again... I feel there should be a way to preserve the web element of frame B and frame C. But I'm not sure how to do it. Thank you very much!

like image 297
Seraph Avatar asked Oct 22 '16 08:10

Seraph


People also ask

How do I refresh a webpage in Selenium Python?

We can refresh a webpage using Selenium webdriver in Python. This can be done with the help of the refresh method. First of all, we have to launch the application with the get method. Once a web page is loaded completely, we can then refresh the page with the help of the refresh method.

How do you refresh a page in Python?

To refresh a web page using the selenium module in Python, we use the refresh() function. This is shown in the code below. The refresh() will refresh the web page, acting just like the refresh button of a web browser or clicking the 'F5' button on your keyboard.

How many ways we can refresh browser in Selenium?

4 Ways to Refresh Page In Selenium Webdriver.


1 Answers

You actually can, at least with a recent version of Selenium.

Here is my code:


from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import selenium.webdriver.support.expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import pathlib

# For testing purpose I've created a local HTML page
path = pathlib.Path(__file__).parent.absolute()
url = 'file:///%s/main.html' % path

browser = webdriver.Chrome(executable_path=r"chromedriver.exe")
browser.get(url)

w = WebDriverWait(browser, 5)

# Switch to Frame A
w.until(EC.frame_to_be_available_and_switch_to_it(("frameA")))

# Switch to Frame B
w.until(EC.frame_to_be_available_and_switch_to_it(("frameB")))

# Keep a reference of the refresh button
buttonB = browser.find_element_by_id("refresh")

while True:
    # Click the refresh
    buttonB.click()

    # Wait for frame load and switch to Frame C
    w.until(EC.frame_to_be_available_and_switch_to_it(
        (By.NAME, "frameC")
    ))

    # Switch back to parent frame aka FrameB
    browser.switch_to.parent_frame()

    # Testing loop
    print('Waiting for commands')
    time.sleep(10)

I've tested the code with a bunch of local html pages:

<!-- main.html -->
<h1>MAIN PAGE</h1>
<div id="tick"></div>
<iframe name="frameA" src="frameA.html" width="800" height="600"></iframe>
<script type="text/javascript">
    document.getElementById("tick").innerText = "Time: " + new Date().getTime();
</script>
<!-- frameA.html -->
<h2>FRAME A</h2>
<div id="tick"></div>
<iframe name="frameB" src="frameB.html" width="700" height="500"></iframe>
<script type="text/javascript">
    document.getElementById("tick").innerText = "Time: " + new Date().getTime();
</script>
<!-- frameB.html -->
<h3>FRAME B</h3>
<button id="refresh" onclick="refresh()"></button>
<iframe id="frameC" name="frameC" src="https://currentmillis.com/" width="600" height="400"></iframe>
<script type="text/javascript">
    document.getElementById("refresh").innerText = "Time: " + new Date().getTime();
    var refresh = function(){
        var frameC = document.getElementById('frameC');
        frameC.src = frameC.src;
    }
</script>

As you can see, every "Time" label is followed by a timestamp of when the single page is loaded, this is much clearer with the following image, where you can see that each "Time" is loaded once, except the inner FrameC that loads the updated timestam from the actual website.

enter image description here

like image 156
Mattia Galati Avatar answered Oct 21 '22 23:10

Mattia Galati