The objective I am pursuing is the following: I want to be able to open a web site or web application and show a floating toolbar on top of the web site’s content. As I am making my way through the site or application, I can use functions from the toolbar – such as taking a snapshot of the current page state and saving it to file, downloading all images in the current page, fill in the form fields using predefined or random values and start a demo.
What I want to do this time is:
- creating a floating, fixed, semi-transparant toolbar – using HTML and CSS
- add this toolbar – using Playwright – on top of a site or app that is loaded into the embedded browser
- ensure that the toolbar stays around whenever the browser is navigated to a new page (it probably needs to be added again after a page is refreshed or loads from, a new URL)
- implement the Snapshot function linked to a toolbar option: when the option is triggered, the Playwright function for taking a snapshot of the page is activated. Note: the toolbar itself should be hidden at the time of taking the snapshot
- show and hide the toolbar using a short cut key combination
- add a toolbar option for loading all images in a page
The next challenge I have identified: using Playwright, I want to create a demonstration of a web application or web site. Playwright commands are used to perform the actions in the web page. What is special, is that these actions are to be grouped in steps. Together, these steps form a scenario. Using the toolbar – the user can play (one or more steps), pause, skip (a step), reset (return execution to the first step). In between the execution of the automated steps, the user can interact freely with the web page. The demo steps do not have to be executed or they do not need to be the only thing that is done. Each step can have a title and a description that could be shown in the toolbar. Additionally, associated with a step can be a call out – a text balloon or an arrow with text – that can be positioned on top the page near the element that is manipulated in the step.
In this way, demo scripts or tutorials can be created that take a user by the hand in a live web environment. The user can choose to let the prepared scenario play out or to intervene, contribute or event take over (in part).
As a next step, we could create multiple scenarios for a page or app and the user could choose a scenario to execute in the context of a page. At any point, the user can decide to run a different scenario.
Note: all code for this article is available on GitHub: https://github.com/lucasjellema/playwright-scenarios/tree/main/floating_menu.
1 creating a floating, fixed, semi-transparent toolbar – using HTML and CSS
My best resources for creating the floating toolbar was W3 Schools (https://www.w3schools.com/howto/howto_js_navbar_sticky.asp and others). This is what I have created:
Each item is an link. When the link is clicked, an action can be triggered.
The HTML and CSS is relatively simple. First the CSS:
2. Add this toolbar on top of a site or app that is loaded into the embedded browser using Playwright
The toolbar is added to the DOM as child of the BODY element. Whenever the DOM is refreshed and the BODY element is discarded, the toolbar disappears along with it. Because the initscript is executed by Playwright after every action that may have destroyed BODY and toolbar, we have made sure that the toolbar stays around (== gets recreated) whenever the browser is navigated to a new page.
This code refers to two constants that define the CSS and HTML respectively:
3. Implement the Snapshot function linked to a toolbar option
When the option is triggered, the Playwright function for taking a snapshot of the page is activated. Note: the toolbar itself should be hidden at the time of taking the snapshot. The toolbar option Take Snapshot is linked up to the function window.snapshotFunction:
<li style=”float:right”><a class=”active” onclick=”window.snapshotFunction(‘FloatingDemo’)”>Take Snapshot</a></li>
This function is injected into the window object through the following call:
await context.exposeBinding(‘snapshotFunction’, snapshotter)
The function is a proxy (in the browser context) for the function snapshotter (in the Node context). This function is defined as follows:
The function gets a handle on the toolbar (through the page.$eval) and hides the div (using style,.display = ‘none’. Next, the name of the snapshot file is derived – including the label parameter and the timestamp – and the snapshot is taken and saved – by Playwright’s function screenshot on the page object. Subsequently, the toolbar is made visible again.
At this point, the Take Snapshot functi0n in the toolbar is active. When a page is loaded in the embedded Playwright browser, a snapshot is taken by clicking the toolbar option.
In this example, I have loaded the Playwright home page at https://playwright.dev/. I have taken a snapshot, navigate to the documentation section and scrolled the page and taken a second snapshot. The bottom of the figure shows VS Code with the two snapshot files open. Note that the toolbar is not part of the snapshot.
4. Show and hide the toolbar using a short cut key combination
The toolbar can be in the way at times, so it would be good to be able to hide it. And show it again. We can do so using a short cut key. In this article I have described how to inject a short cut key through Playwright to any page. Following the instructions from this article, it is relatively easy to set up the shortcut key CTRL+B for toggling the toolbar between hidden and visible.
Finally, the call to document.addEventListener() configures function handleShortCutKey() as an handler for keyUp events.
The two function definitions and this final call to document.addEventListener() are all defined in const shortCutJS. This const is added to the content passed in addInitScript and will therefore be executed in each page and frame. Whenever we run a page, the toolbar is added and we can hide it with CTRL+b and bring it back with that same combination.
5. Add a toolbar option for loading all images in a page
This step is not strictly required – but it is fun and given all the pieces we already have it is a puzzle that is easy to solve. Also read my previous article on adding a short cut key to download all images: https://technology.amis.nl/2020/12/24/use-playwright-to-inject-shortcut-keys-into-any-web-page-for-example-to-download-all-images/
First, add an option in the toolbar to Save All Images:
Then define the function allImageDownloader with all it requires (including function streamImageFromURL, const IMAGE_PATH and the require statements for request and fs.
Finally, expose this function allImageDownloader in the window object to make it available to the onclick action on the toolbar option:
So: toolbar has link with onclick action; this invokes window.saveAllImagesFunction in the browser context. This call is forwarded to the Node function allImageDownloader. This function locates all images in the current page and retrieves their content from the image src url and saves it to the local images directory.
The toolbar has the extra option to save images. I have loaded a Dutch news site.
Before pressing the Save Images, this is what the image folder looked like in VS Code:
And this is what it looks like after pressing the toolbar option:
All code for this article is available on GitHub: https://github.com/lucasjellema/playwright-scenarios/tree/main/floating_menu.
My previous article: Use Playwright to Inject Shortcut Keys into Any Web Page – for example to download all images – https://technology.amis.nl/2020/12/24/use-playwright-to-inject-shortcut-keys-into-any-web-page-for-example-to-download-all-images/
I have introduced Playwright in an earlier article
W3Schools on Horizontal Navigation Bars – https://www.w3schools.com/howto/howto_js_navbar_slide.asp and others
PlayWright documentation on AddInitScript: https://microsoft.github.io/playwright/docs/1.6.1/api/class-browsercontext#browsercontextaddinitscriptscript-arg