Skip to content

[Feature]: removeExposedFunction #31668

@mithrandirmatt

Description

@mithrandirmatt

🚀 Feature Request

Others have seemed to find work arounds for this, but when creating a new context all my data set by previous context are blown away.

Example.

playwright -> browser ui layer -> web worker -> data

When a set a async wait to update a value it must first communicate to the UI layer.

The UI layer will track the name of the exposed function, and then send a write request to the web worker.

The web worker will get the request, then update the value, then on change event within the web worker thread will communicate back to the UI layer (postMessage). The UI thread then calls the callback that was exposed within the function.

data -> web worker -> browser ui layer -> exposedFunction -> playwright

I am done monitoring that piece of data for the moment, now time to do other stuff.

This other stuff can affect the same data, so later I will want to watch it.

If a create a new context at this point, as suggested by previously rescinded tickets, the previously set data in the web worker is lost due to a new session.

I have seen other issues, requesting this feature, but maybe without adequate expression as to why it is needed.

Making these into reusable code snippets cuts down on the time a developer needs to take to write code. If it is as simple as freeing up the previously exposed function to save 15-20 mins of time a few hundred or even thousands of times, then this is a must have feature.

I have hundreds of data parameters that can be set and updated, if I have to write 10-15 lines of code for each one vs 1 line of reusable code, this is major savings.

Puppeteer already supports this, as a use case likely arose to necessitate its existence. Probably in the same context of reusability I would imagine.

https://pptr.dev/api/puppeteer.page.removeexposedfunction

17836, 30422, 30732... and potentially others have requested this feature to only be met with disregard.

Keep in mind this web worker that I need to keep alive within the same session:

playwright -> browser ui layer -> ( web worker -> data -> web worker ) -> browser ui layer -> playwright

Allowing a generic bind/unbinding process frees up un-needed workarounds or extra code. The browser allows us to bind/unbind, why wouldn't a browser tester?

I have worked around this issue by appending and tracking names, bloating the SW at runtime and another 40 lines or so of code, but I still think that the correct way to do this is with a proper bind/unbind process.

Example

These are async reusable functions to cut down on repetitive code.

Each function will spawn its own generic and local callback via exposeFunction.

Each function doesn't need to track any previous async calls/data/etc, as each session is a "new" session to be released and forgotten once it has facilitated is job function.

// Will listen for change, set new data, and wait for the new data to match (or timeout)
expect( await subscribe_set_and_wait( page, "data_name", set_value ) ).toEqual(true);

... do some stuff... expect data to change specific value.

// Will list for change, and wait for the expected data to match or timeout before proceeding.
expect( await subscribe_and_wait( page, "data_name", expected_value ) ).toEqual(true);

When I hit this second subscribe and wait, the error:

Error: page.exposeFunction: Function "data_name" has been already registered.

The context created within the async function has already facilitated its duty and is no longer needed, yet the browser is hanging onto the old context, and the library, presumably prevents subsequent exposes with the same name.

Motivation

Velocity. Reusability.

Sanity, no one wants to write code that doesn't need to be repeated.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions