question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Too hard to define a custom command wrapping a RPC

See original GitHub issue

Current behavior:

Given existing documentation and reading the source code I was trying today the whole day to define a custom command wrapping a simple node-style callback RPC. In my view this is much harder than it should be if you want a perfect integration and native (like official commands) feel to this command.

First, it seems that very important Cypress.log is barely documented and one has to go through the source code to really understand it, where also very limited comments do not help.

Then there are the following issues:

  • It seems it is not possible to get same treatment in log as XHR request, to get loading icon to show while the call is in progress. I have tried to setup log and then use log.end() call to signal when is start and end if the request, but it does not seem to have the effect.
  • It is not really possible to hide internal commands. I tried to use {log: false} everywhere, but not all commands support that (like its I used), or if they do, internal commands still leak, for example, if my RPC call takes too long, then the error message about timeout comes from then instead of my custom command.
  • While log.error() marks the entry in the log red, it does not really make the whole process fail.
  • It is unclear how one can return a subject in an async manner. An example in documentation would be great. In my case, I would like to return of the RPC as the subject from the command. I found verifyUpcomingAssertions but I am not sure how to use it, there was no documentation for it I could find.
  • It is unclear how one can define a custom command which is partially retriable (like fetching the RPC object from window) but not fully (like I want RPC to be done only once).

This is to where I got:

Cypress.Commands.add('call', (methodName, ...args) => {
  const options = {};

  options._log = Cypress.log({
    name: 'call',
    message: `${methodName}(${Cypress.utils.stringify(args)})`,
    consoleProps() {
      return {
        methodName,
        arguments: args,
      };
    },
  });

  return cy.window({log: false}).its('RPC').then({log: false}, (RPC) => {
    try {
      return new Promise((resolve, reject) => {
        RPC.call(methodName, ...args, (error, result) => {
          options._log.set({
            consoleProps() {
              return {
                methodName,
                arguments: args,
                error,
                result,
              };
            },
          });

          if (error) {
            options._log.error(error);
          }
          else {
            options._log.end();
            cy.verifyUpcomingAssertions(result, options);
          }
          resolve();
        });
      });
    }
    catch (error) {
      options._log.set({
        consoleProps() {
          return {
            methodName,
            arguments: args,
            error,
          };
        },
      }).error(error);
    }
  });
});

Versions

Cypress 3.1.0.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:20 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
jennifer-shehanecommented, Sep 10, 2018

Thank you for the thoughtful write-up. I agree with all of your points and think most of them would be solved by better documentation of the Cypress.log command.

Looped in some of the team to hopefully get some of your current questions answered.

1reaction
egucciarcommented, Oct 23, 2018

@jennifer-shehane i’d really love if we could get some insight on this sooner…Just knowing how to show the pending spinner would be great.

EDIT: Got it figured out

  1. At the beginning of the custom command, create a Cypress.log and store it to set off the spinner:
const log = Cypress.log({
    message: 'Your message'
});
  1. return a Promise from your Command to invoke the spinner for the duration of your async command

  2. When Resolving, Mutate log when the Command resolves to pass in yielded argument properties (consoleProps, $el, etc) e.g.

// async got some elements
log.$el = foundElements
  1. When Rejecting, catch the rejected error (or otherwise prevent legitimate failure) & rethrow using:
    // err can be the caught error / rejection
    Cypress.utils.throwErr(err, {
      onFail: log
    })

☝️ thats correct -> pass log into the onFail handler, and boom. Pretty Cypress-y commands.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Too hard to define a custom command wrapping a RPC #1394
Given existing documentation and reading the source code I was trying today the whole day to define a custom command wrapping a simple...
Read more >
Understanding RPC Vs REST For HTTP APIs
This article discusses REST and RPC in the context of building HTTP APIs. Knowing their differences can be incredibly useful for either ...
Read more >
or how REST is no longer the only respectable solution for APIs
I've used Gradle to build the code and Java 8 and Groovy to implement the servers/clients, but whatever stack you use, the procedure...
Read more >
Tufts CS 117 Assignment -
In this assignment, you will implement your own remote procedure call system which will provide transparency for the invocation of simple C++ functions ......
Read more >
Terminal prompt not wrapping correctly - Unix Stack Exchange
So using the command env -i bash --norc fixes it. The $COLUMNS and $LINES match. Does that mean that there's something funny with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found