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...