IFrame Handling

This tutorial demonstrates how to work with iframes in Widgetastic.core using the framework’s test pages. You’ll learn to navigate iframe hierarchies, switch contexts, and handle nested frame structures using iframe_page.html and iframe_page2.html.

Note

Prerequisites: Basic widgets tutorial Test Pages Used: testing/html/testing_page.html, iframe_page.html, iframe_page2.html

Learning Objectives

  • ✅ Understand iframe context switching

  • ✅ Navigate nested iframe hierarchies

  • ✅ Handle iframe isolation and cross-context access

Understanding IFrames in Web Automation

IFrames (inline frames) embed another HTML document within the current page. They create isolated contexts that require special handling in web automation:

  • Context Isolation: Elements inside iframes aren’t accessible from the main page context

  • Frame Switching: You must explicitly switch context to interact with iframe content

  • Nested Frames: IFrames can contain other iframes, creating complex hierarchies

  • Security Boundaries: Cross-origin iframes may have additional restrictions

Basic IFrame Access

The testing page contains an iframe that loads iframe_page.html. Here’s how to access it:

Simple IFrame View

 1"""Basic IFrame Access
 2
 3This example demonstrates accessing elements inside an iframe.
 4"""
 5
 6from widgetastic.widget import View, Text, Select
 7
 8
 9class BasicIFrameView(View):
10    # The FRAME attribute specifies the iframe locator
11    FRAME = '//iframe[@name="some_iframe"]'
12
13    # Widgets inside the iframe
14    iframe_title = Text(".//h3")
15    select1 = Select(id="iframe_select1")
16    select2 = Select(name="iframe_select2")
17
18
19iframe_view = BasicIFrameView(browser)  # noqa: F821
20
21# Test basic iframe access
22print(f"IFrame displayed: {iframe_view.is_displayed}")
23print(f"IFrame title: {iframe_view.iframe_title.read()}")
24
25# Interact with iframe widgets
26current_selection = iframe_view.select1.read()
27print(f"Current selection: {current_selection}")
28
29# Change selection
30iframe_view.select1.fill("Bar")
31print(f"New selection: {iframe_view.select1.read()}")
32
33# Working with multi-select in iframe
34print(f"Multi-select options: {iframe_view.select2.all_options}")
35
36# Select multiple options
37iframe_view.select2.fill(["Foo", "Baz"])
38selected = iframe_view.select2.read()
39print(f"Multi-selected: {selected}")
40
41# Clean up: Return to main frame
42browser.switch_to_main_frame()  # noqa: F821

Nested IFrame Navigation

The iframe testing setup includes nested iframes. Here’s how to handle complex hierarchies:

Nested IFrame Structure

 1"""Nested IFrame Navigation
 2
 3This example demonstrates handling nested iframes (iframe within iframe).
 4"""
 5
 6from widgetastic.widget import View, Text, Select, TextInput
 7
 8
 9class NestedIFrameView(View):
10    # First level iframe
11    FRAME = '//iframe[@name="some_iframe"]'
12    iframe_title = Text(".//h3")
13
14    # Nested iframe class (iframe within iframe)
15    @View.nested
16    class nested_iframe(View):  # noqa
17        FRAME = './/iframe[@name="another_iframe"]'
18        nested_title = Text(".//h3")
19        nested_select = Select(id="iframe_select3")
20
21        # Deeply nested view within the nested iframe
22        @View.nested
23        class deep_nested(View):  # noqa
24            ROOT = './/div[@id="nested_view"]'
25            nested_input = TextInput(name="input222")
26
27
28nested_view = NestedIFrameView(browser)  # noqa: F821
29
30# Access each level of nesting
31print(f"Level 1 iframe: {nested_view.iframe_title.read()}")
32print(f"Level 2 iframe: {nested_view.nested_iframe.nested_title.read()}")
33print(f"Nested select: {nested_view.nested_iframe.nested_select.read()}")
34
35# Access deeply nested input
36nested_input_value = nested_view.nested_iframe.deep_nested.nested_input.read()
37print(f"Deep nested input: {nested_input_value}")
38
39# Fill deeply nested input
40nested_view.nested_iframe.deep_nested.nested_input.fill("Updated Value")
41updated_value = nested_view.nested_iframe.deep_nested.nested_input.read()
42print(f"Updated nested input: {updated_value}")
43
44# Clean up: Return to main frame
45browser.switch_to_main_frame()  # noqa: F821

IFrame Context Isolation

IFrame contexts are completely isolated. Elements in different frames cannot directly interact:

Demonstrating Context Isolation

 1"""IFrame Context Isolation
 2
 3This example demonstrates that iframe contexts are completely isolated.
 4"""
 5
 6from widgetastic.widget import View, Text, Select, Checkbox
 7
 8
 9class MainPageView(View):
10    # Elements in main page context
11    main_title = Text("h1#wt-core-title")
12    main_checkbox = Checkbox(id="switchabletesting-3")
13
14
15class IFrameView(View):
16    FRAME = '//iframe[@name="some_iframe"]'
17    iframe_title = Text(".//h3")
18    iframe_select = Select(id="iframe_select1")
19
20
21main_view = MainPageView(browser)  # noqa: F821
22iframe_view = IFrameView(browser)  # noqa: F821
23
24# Both contexts work independently
25print(f"Main page title: {main_view.main_title.read()}")
26print(f"IFrame title: {iframe_view.iframe_title.read()}")
27
28# Interactions don't affect each other
29print("Testing context isolation:")
30main_view.main_checkbox.fill(True)
31iframe_view.iframe_select.fill("Bar")
32
33# Verify isolation - both maintain their states
34main_checkbox_state = main_view.main_checkbox.read()
35iframe_select_state = iframe_view.iframe_select.read()
36
37print(f"Main checkbox state: {main_checkbox_state}")
38print(f"IFrame select state: {iframe_select_state}")
39
40if main_checkbox_state is True and iframe_select_state == "Bar":
41    print("✓ Context isolation verified")
42
43# Clean up: Return to main frame
44browser.switch_to_main_frame()  # noqa: F821