# class: Frame * since: v1.8 At every point of time, page exposes its current frame tree via the [`method: Page.mainFrame`] and [`method: Frame.childFrames`] methods. [Frame] object's lifecycle is controlled by three events, dispatched on the page object: * [`event: Page.frameAttached`] - fired when the frame gets attached to the page. A Frame can be attached to the page only once. * [`event: Page.frameNavigated`] - fired when the frame commits navigation to a different URL. * [`event: Page.frameDetached`] - fired when the frame gets detached from the page. A Frame can be detached from the page only once. An example of dumping frame tree: ```js const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'. (async () => { const browser = await firefox.launch(); const page = await browser.newPage(); await page.goto('https://www.google.com/chrome/browser/canary.html'); dumpFrameTree(page.mainFrame(), ''); await browser.close(); function dumpFrameTree(frame, indent) { console.log(indent + frame.url()); for (const child of frame.childFrames()) { dumpFrameTree(child, indent + ' '); } } })(); ``` ```java import com.microsoft.playwright.*; public class Example { public static void main(String[] args) { try (Playwright playwright = Playwright.create()) { BrowserType firefox = playwright.firefox(); Browser browser = firefox.launch(); Page page = browser.newPage(); page.navigate("https://www.google.com/chrome/browser/canary.html"); dumpFrameTree(page.mainFrame(), ""); browser.close(); } } static void dumpFrameTree(Frame frame, String indent) { System.out.println(indent + frame.url()); for (Frame child : frame.childFrames()) { dumpFrameTree(child, indent + " "); } } } ``` ```python async import asyncio from playwright.async_api import async_playwright async def run(playwright): firefox = playwright.firefox browser = await firefox.launch() page = await browser.new_page() await page.goto("https://www.theverge.com") dump_frame_tree(page.main_frame, "") await browser.close() def dump_frame_tree(frame, indent): print(indent + frame.name + '@' + frame.url) for child in frame.child_frames: dump_frame_tree(child, indent + " ") async def main(): async with async_playwright() as playwright: await run(playwright) asyncio.run(main()) ``` ```python sync from playwright.sync_api import sync_playwright def run(playwright): firefox = playwright.firefox browser = firefox.launch() page = browser.new_page() page.goto("https://www.theverge.com") dump_frame_tree(page.main_frame, "") browser.close() def dump_frame_tree(frame, indent): print(indent + frame.name + '@' + frame.url) for child in frame.child_frames: dump_frame_tree(child, indent + " ") with sync_playwright() as playwright: run(playwright) ``` ```csharp using Microsoft.Playwright; using System; using System.Threading.Tasks; class FrameExamples { public static async Task Main() { using var playwright = await Playwright.CreateAsync(); await using var browser = await playwright.Firefox.LaunchAsync(); var page = await browser.NewPageAsync(); await page.GotoAsync("https://www.bing.com"); DumpFrameTree(page.MainFrame, string.Empty); } private static void DumpFrameTree(IFrame frame, string indent) { Console.WriteLine($"{indent}{frame.Url}"); foreach (var child in frame.ChildFrames) DumpFrameTree(child, indent + " "); } } ``` ## async method: Frame.addScriptTag * since: v1.8 - returns: <[ElementHandle]> Returns the added tag when the script's onload fires or when the script content was injected into frame. Adds a `