How to make a custom playwright node for local use no paid API?

It would help if there was a node for: Playwright locally with chromium

My use case:

I frequently need to automate browser tasks such as taking screenshots, navigating webpages, and interacting with web elements as part of my workflows in n8n. While Puppeteer has been an option, I encountered stability issues and limited functionality for my needs. Playwright offers a more robust and versatile API, supporting multiple browsers and providing enhanced capabilities. However, integrating Playwright directly into n8n requires writing custom scripts, which can be cumbersome for users who prefer a no-code solution.

A dedicated Playwright node for n8n would allow users to:

Capture Screenshots: Easily take full-page or element-specific screenshots without writing code.
Navigate and Interact: Automate navigation, clicks, form submissions, and other interactions on webpages.
Cross-Browser Support: Utilize Chromium, Firefox, and WebKit browsers seamlessly within workflows.
Error Handling: Incorporate robust error handling for web automation tasks.
Scheduling and Automation: Integrate with n8n’s scheduling features to perform regular web tasks automatically.

This node would simplify the integration of web automation tasks into n8n workflows, making powerful browser automation accessible to a broader range of users.

Are you willing to work on this?
Yes i am willing i just dont know how to create the code into a node that i can use and anyone else who would want this. because it seems no one has made one all of them need paid API and i dont want that.

here is a code from chatgpt o1 min but idk if it will work,

import { IExecuteFunctions } from 'n8n-core';
import { INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
import { chromium } from 'playwright';

export class Playwright implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'Playwright',
		name: 'playwright',
		icon: 'file:playwright.svg',
		group: ['transform'],
		version: 1,
		description: 'Automate browser tasks using Playwright',
		defaults: {
			name: 'Playwright',
			color: '#772244',
		},
		inputs: ['main'],
		outputs: ['main'],
		properties: [
			{
				displayName: 'Action',
				name: 'action',
				type: 'options',
				options: [
					{
						name: 'Take Screenshot',
						value: 'screenshot',
						description: 'Take a screenshot of a webpage',
					},
					// Add more actions here
				],
				default: 'screenshot',
				description: 'The action to perform.',
			},
			{
				displayName: 'URL',
				name: 'url',
				type: 'string',
				default: '',
				required: true,
				description: 'The URL of the webpage to capture.',
			},
			{
				displayName: 'Output Path',
				name: 'outputPath',
				type: 'string',
				default: 'screenshot.png',
				description: 'The path where the screenshot will be saved.',
			},
			// Add more parameters based on actions
		],
	};

	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
		const items = this.getInputData();
		const returnData: INodeExecutionData[] = [];

		for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
			try {
				const action = this.getNodeParameter('action', itemIndex) as string;
				const url = this.getNodeParameter('url', itemIndex) as string;
				const outputPath = this.getNodeParameter('outputPath', itemIndex) as string;

				if (action === 'screenshot') {
					const browser = await chromium.launch();
					const page = await browser.newPage();
					await page.goto(url, { waitUntil: 'networkidle' });
					await page.screenshot({ path: outputPath, fullPage: true });
					await browser.close();

					returnData.push({
						json: {
							message: `Screenshot saved to ${outputPath}`,
						},
						binary: {},
					});
				}

				// Implement more actions here
			} catch (error) {
				if (this.continueOnFail()) {
					returnData.push({
						json: {
							error: error.message,
						},
					});
					continue;
				}
				throw error;
			}
		}

		return this.prepareOutputData(returnData);
	}
}