Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Current Limitations blocking Cypress' adoption of Webdriver BiDi For Firefox #30447

Open
1 of 3 tasks
AtofStryker opened this issue Oct 23, 2024 · 6 comments
Open
1 of 3 tasks

Comments

@AtofStryker
Copy link
Contributor

AtofStryker commented Oct 23, 2024

Cypress has spent a few weeks on prepping our firefox automation to cut over from CDP to BiDi. There was some precursor work to do this, such as moving to geckodriver and webdriver in order to have access to a BiDi client on modern automation infrastructure.

Since doing this, we have spiked into cutting over to BiDi, which more details can be seen in the spike issue comment #30351 (comment).

From what I can see, there are a few blockers for us right now from moving over to BiDi from CDP. This is also being tracked on Firefox's side in https://bugzilla.mozilla.org/show_bug.cgi?id=1604723.

Priority issues for Cypress in the Bidi Context is cuirrently captured in Webdriver Bidi Roadmap Planning (Cypress Copy). The Cypress team is currently going through issues to prioritize support that we want/need. Original document is here and will hopefully merge our priorities upstream soon.

Our mapping of CDP/web extension methods to BiDi methods is currently captured in the
Cypress State of Automation document.

The below checklist is representative from the above link to roadmap planning, reflect P2 issues and under (p1 is more severe than p2)

  • P1: Add Support for resourceType to network events. Issue tracked in https://bugzilla.mozilla.org/show_bug.cgi?id=1904892 and mentioned in https://bugzilla.mozilla.org/show_bug.cgi?id=1604723. This is critical to Cypress to support cookie management, proxy logging, proxy correlation, and the cy.intercept() API. UPDATE: December 13th, 2024 This can now be mapped via the initiatorType added in Expose initiatorType and destination on network.Request w3c/webdriver-bidi#809 which removes the major blocker for us to move to BiDi. This should be available in Firefox 135.
  • P3: File download behavior. The W3C API has browsingContext.downloadWillBegin, but this doesn't look to be currently supported as a "no event exist" error is thrown. Cypress also would need something like Page.downloadComplete in CDP to fully move this out of our web extension. We currently work around this in our web extension so it isn't a blocker to base adoption.
  • P2: Be able to load web extensions and access background page. This is currently supported through classic webdriver through firefox specific capabilities. We just want to make sure this is supported in the future if classic webdriver is removed, but isn't a blocker to base adoption.
@christian-bromann
Copy link

@AtofStryker this is really exciting to see Cypress adopting WebDriver Bidi primitives. If there is anything I can help with from the WebdriverIO project, e.g. any issues you encounter on the webdriver or geckodriver package, please reach out!

@AtofStryker
Copy link
Contributor Author

@AtofStryker this is really exciting to see Cypress adopting WebDriver Bidi primitives. If there is anything I can help with from the WebdriverIO project, e.g. any issues you encounter on the webdriver or geckodriver package, please reach out!

Thank you @christian-bromann. We are mainly blocked on the resourceType issue, but once that makes its way into the protocol we will give it another try. I will reach out if we need anything!

@AtofStryker
Copy link
Contributor Author

AtofStryker commented Dec 13, 2024

updated BIDI_AUTOMATION_CLIENT_NO_RESOURCE_TYPE (from linked comment in description) on branch webdriver_ff_no_resource https://github.com/cypress-io/cypress/compare/release/14.0.0...webdriver_ff_no_resource?expand=1 to get things based off cypress 14 and try destination, which was add in firefox nightly 135 as noted in https://bugzilla.mozilla.org/show_bug.cgi?id=1604723#c35. We still need a genuine resource type as destination is only going to tell us where the resource is going, which looks to be right now either a script, style, image, or iframe. currently investigating initiator type which has xmlhttprequest and fetch so it should give us what we need.

Update: initiator type mapping works and is implemented in 072bd68 off of webdriver_ff_no_resource

@melibe23
Copy link

With v14 how can we hide network logs like fetch/xhr now? Thanks!

@AtofStryker
Copy link
Contributor Author

With v14 how can we hide network logs like fetch/xhr now? Thanks!

@melibe23 you should be able to do this the same way currently. The field is currently deprecated but its still there!

@adamalston
Copy link

Hi, we use resourceType for a few things.

  1. Asserting that requests were or weren't sent while performing a set of actions.
// cypress/support/index.d.ts
/**
 * Checks requests made during the execution of a set of actions.
 * @param actions A set of actions to perform while intercepting requests.
 * @param requests Expected requests triggered by the actions.
 * @param depth Depth of the comparison for matching requests.
 * - deep: Checks that the intercepted requests and the provided requests
 *   are equal in every way.
 * - shallow: Checks that the intercepted requests and the provided requests
 *   are equal in content and count.
 * - ...
 */
checkRequests(
  actions: () => void,
  requests: { method: string; url: string; }[],
  depth: 'absent' | 'deep' | 'shallow' | 'subset',
): Chainable<Subject>;

// cypress/support/commands.ts
const { baseUrl } = Cypress.config();

Cypress.Commands.add('checkRequests', (actions, requests, depth) => {
  const uuid = crypto.randomUUID();

  cy.intercept({ resourceType: /fetch|xhr/ }).as(uuid);
  actions();

  cy.get<Interception[]>(`@${uuid}.all`, { timeout: 0 }).should(
    depth === 'deep' || depth === 'shallow' ? 'have.length' : 'have.length.gte',
    requests.length,
  );

  switch (depth) {
    case 'deep':
      cy.get<Interception[]>(`@${uuid}.all`).then((interceptions) => {
        cy.wrap(
          interceptions.map(({ request: { method, url } }) => ({
            method,
            url: url.replace(baseUrl ?? '', ''),
          })),
        ).should('deep.eq', requests);
      });
      break;
    // ...
  }
});
  1. Asserting requests to load fonts.
const uuid = crypto.randomUUID();
const expectedRequests = [/* Requests. */];

cy.intercept({
  resourceType:
    /document|fetch|xhr|websocket|stylesheet|script|image|font|cspviolationreport|ping|manifest|other/,
}).as(uuid);

// ...

cy.get<Interception[]>(`@${uuid}.all`).then((interceptions) => {
  const resolvedRequests = expectedRequests.reduce<string[]>(
    (acc, { method, url }) => {
      const resolvedUrl = '/* Processing. */';

      return !resolvedUrl
        ? acc
        : [...acc, JSON.stringify({ method, url: resolvedUrl })];
    },
    [],
  );

  const formattedInterceptions = interceptions.map(
    ({ request: { method, url } }) => JSON.stringify({ method, url }),
  );

  cy.wrap(formattedInterceptions).should('have.members', resolvedRequests);
});

Note that I've removed and altered code in the above snippets given the confidential nature of many things I work on.

On https://github.com/cypress-io/cypress-documentation/blob/639cfea75339dd6b617073e99ea2d5661a4010b6/docs/app/references/migration-guide.mdx?plain=1#L98-L103, the two use cases above cover all resource types. Given that, I think they're all important. fetch and xhr are the most important.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
@christian-bromann @AtofStryker @adamalston @melibe23 and others