Investigate "promise chaining" technique to improve the action API testing utilities.
Status Quo: The actionapi module provides several utility functions for accessing different functionality of the action API, e.g. action, login, list, prop, meta, and edit. Some of them have an optional parameter that causes then to use the POST method instead of GET. For testing for a negative outcome of a request, there is the actionError method.
Problem: actionError is inconvenient to use, we'd need to duplicate several methods, like editError, loginError, etc. With the need to synchronize between requests (see T230211), while preserving the option to not sync and test for race conditions, means we'd again have to duplicate, e.g. actionNoSync, editNoSync, etc.
Solution: use the "promise chaining" technique to configure requests using a "fluent" style interface, like so:
await alice.edit(title, "hello world").error("permission-denied"); await alice.action('block', { user }).post().sync( false );
Note that this task is made a bit more complex by the fact that some of these utility functions need to aquire tokens before the actual request can execute - that is, they have to make themselves follow another promise:
await alice.action('block', { user }).after( () = { token: await alice.token('csrf') } ).post().sync( false );
..or something like this...