evaluate(mainFn, options) {
    const argsSerialized = ExecutionContext.serializeArguments(options.args);
    const depsSerialized = ExecutionContext.serializeDeps(options.deps);

    const expression = `(() => {
      ${depsSerialized}
      return (${mainFn})(${argsSerialized});
    })()`;
    return this.evaluateAsync(expression, options);
  }
Evaluate a function in the context of the current page.
If `useIsolation` is true, the function will be evaluated in a content script that has
access to the page's DOM but whose JavaScript state is completely separate.
Returns a promise that resolves on a value of `mainFn`'s return type.
@template {unknown[]} T, R
@param {((...args: T) => R)} mainFn The main function to call.
@param {{args: T, useIsolation?: boolean, deps?: Array<Function|string>}} options `args` should
  match the args of `mainFn`, and can be any serializable value. `deps` are functions that must be
  defined for `mainFn` to work.
@return {Promise<Awaited<R>>}