Create OCI Function running a Playwright scenario

Lucas Jellema
Jan 4 · 5 min read

TL;DR — How to create a Function on Oracle Cloud Infrastructure that uses the Playwright library for running headless browser scenarios, for example for Web UI Health Check and Performance Monitoring, for tactical integration and simple RPA and for web based reporting. The article shows a custom Docker container image based on a community container image for headless chrome and Playwright with a custom Node application that interacts with the Google Translate web ui; the Project Fn hotwrap utility is added to this image to provide the bridge from the OCI FaaS serverless function framework based on Project Fn to the custom Node application. This approach can be used for any Playwright scenario and also for other custom Docker container images not related to Playwright.

Sources for this article on GitHub: https://github.com/lucasjellema/playwright-scenarios/tree/main/fn

Image for post
Image for post
Project Fn Function implemented by a Node application using Playwright to programmatically interact with Google Translate Web UI

At the heart of the function is a Node application that uses Playwright to interact with the Google Translate Web UI, enter source language, target language and text to translate and reads the translation produced by Google Translate. The Function needs to be implemented with a Docker Container image. An Fn image can be created in three ways:

  • the regular approach: create a new Fn function with runtime node in the Fn CLI; add playwright in package.json and hope it works; because of binary libraries, I fear it will not — and indeed it does not
  • customize the Docker Image used for building the Fn container for the Node runtime — based on this article: https://fnproject.io/tutorials/ContainerAsFunction/ ; this approach too did not seem to work: adding Playwright to this container image did not go smoothly, although it probably can be done
  • create a custom Docker build file that extends from an existing image with Playwright; add the Node application and add HotWrap to provide the bridge between the Fn FaaS framework and the Node application, following this article: https://fnproject.io/tutorials/docker/CustomLinuxContainer/ ; this approach worked out well and is not all that complicated at all.

The starting point for the container that implements the Fn function is the image produced by community project Alpine Chrome project on GitHub for *Chrome running in headless mode in a tiny Alpine image*: https://github.com/Zenika/alpine-chrome/tree/master/with-playwright. This project produces image zenika/alpine-chrome:with-playwright. This image contains Node, Playwright Chromium and supporting binaries, an excellent starting point.

Image for post
Image for post
Composing custom Docker container image — based on Zenika Alpine Chrome image with Playwright Chromium, copying from fnproject/hotwrap and adding Node application resources

In my own image, I need to add of course the Node application that uses Playwright to interact with the Chromium browser that accesses the Google Translate Web UI. Additionally I have to add the HotWrap binary that provides the bridge at runtime between the OCI Functions Fn server framework and the custom code in the container image for the function. Hotwrap takes the input from the function request and makes it available to our custom code via the standard input. Anything the custom application writes to the standard output is takes by hotwrap and returned as the function’s response. Additionally, hotwrap makes HTTP headers sent in the function request available as environment variables inside the container.

The container image declares a CMD to define the startup instruction for the Node application that does the actual work and a final ENTRYPOINT that ensure that hotwrap is main process started when the container is started. The Dockerfile looks like this:

Image for post
Image for post
Dockerfile for custom Docker container image

In Node application app.js I have to cater for the interaction with Hotwrap. The input to the Fn function is intercepted by Hotwrap and made available to the Node code via the standard input. The result from the Node application needs to be written to the standard output in order for Hotwrap to consume it and turn it into the Response body from the Fn function. The app.js code is created like this:

Image for post
Image for post
Node application that bridges between Hotwrap and the actual Node application using Playwright

The real work is done in translate.js. The code in translate.js is not aware of Hotwrap or Fn or the Docker container context. You will find its code in the GitHub repo.

Steps for creating the function are now straightforward, for example through OCI Cloudshell or in any Fn CLI environment:

1. Create a new directory that will contain the function’s resources. Copy these files to this new directory:

Image for post
Image for post

Execute the following commands from within the new directory

2. Build and deploy the function to the application (and the container as well to the registry); Here I have assumed an existing Fn application called lab1

fn deploy -app lab1
Image for post
Image for post

To verify, list the functions in application lab1:

fn list functions lab1

3. Invoke the function:

echo -n '{"sourceLanguage":"en", "targetLanguage":"fr", "text":"Hello World"}' | fn invoke lab1 playwright -content-type application/json
Image for post
Image for post
A few calls to the new Fn Function that performs translations. Average response time is 3.5 seconds. In that time, a browser is instantiated, web UI interaction performed and the result returned and processed.

The full implementation is visualized next:

Image for post
Image for post
The composition of the Fn Custom Docker Container and the interaction flow from Fn function call through hotwrap and Node to Playwright and Google Translate

Of course, this approach with hotwrap can be used for functions implemented on top of any base container image:

Image for post
Image for post
The bare essence of using a custom Docker container image with HotWrap for implementing Fn functions

Resources

Sources for this article on GitHub: https://github.com/lucasjellema/playwright-scenarios/tree/main/fn

Project Home for Fn hotwrap: https://github.com/fnproject/hotwrap

Article on using hotwrap on top of a very simple custom Docker container https://fnproject.io/tutorials/docker/CustomLinuxContainer/

Alpine Chrome project on GitHub for *Chrome running in headless mode in a tiny Alpine image*: https://github.com/Zenika/alpine-chrome/tree/master/with-playwright

Alpine Chrome on Docker Hub — with images for running Playwright applications: https://hub.docker.com/r/zenika/alpine-chrome

Article on Medium “Crafting the perfect container to play with a Headless Chrome” https://medium.zenika.com/crafting-the-perfect-container-to-play-with-a-headless-chrome-d920ec2f3c9b

Microsoft’s Offical Playwright Container on GitHub — https://github.com/microsoft/playwright/tree/master/docs/docker (this was a source of inspiration for the Zenika image)

Originally published at https://technology.amis.nl on January 4, 2021.

Oracle Groundbreakers

Aggregation of articles from Oracle engineers…

Lucas Jellema

Written by

Lucas Jellema is solution architect and CTO at AMIS, The Netherlands. He is Oracle ACE Director, Groundbreaker Ambassador, JavaOne Rockstar and programmer

Oracle Groundbreakers

Aggregation of articles from Oracle engineers, Groundbreaker Ambassadors, ACEs, and the developer community on all things Oracle Cloud. The views expressed are those of the authors and not necessarily of Oracle.

Lucas Jellema

Written by

Lucas Jellema is solution architect and CTO at AMIS, The Netherlands. He is Oracle ACE Director, Groundbreaker Ambassador, JavaOne Rockstar and programmer

Oracle Groundbreakers

Aggregation of articles from Oracle engineers, Groundbreaker Ambassadors, ACEs, and the developer community on all things Oracle Cloud. The views expressed are those of the authors and not necessarily of Oracle.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store