Improve end-to-end test logging by rendering JSHandles (#7959)

Fixes https://github.com/vector-im/element-web/issues/13276

It's still not super pretty, but it works.
This commit is contained in:
Travis Ralston 2022-03-03 07:59:29 -07:00 committed by GitHub
parent f9ad2a5151
commit 75abf03fed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 3 deletions

View file

@ -15,6 +15,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { ConsoleMessage } from "puppeteer";
import { padEnd } from "lodash";
import { ElementSession } from "./session";
export const range = function(start: number, amount: number, step = 1): Array<number> {
@ -51,3 +54,50 @@ export async function applyConfigChange(session: ElementSession, config: any): P
}
}, config);
}
export async function serializeLog(msg: ConsoleMessage): Promise<string> {
// 9 characters padding is somewhat arbitrary ("warning".length + some)
let s = `${padEnd(msg.type(), 9, ' ')}| ${msg.text()} `; // trailing space is intentional
const args = msg.args();
for (let i = 0; i < args.length; i++) {
const arg = args[i];
const val = await arg.jsonValue();
// We handle strings a bit differently because the `jsonValue` will be in a weird-looking
// shape ("JSHandle:words are here"). Weirdly, `msg.text()` also catches text nodes that
// we can't with our parsing, so we trust that it's correct whenever we can.
if (typeof val === 'string') {
if (i === 0) {
// if it's a string, just ignore it because it should have already been caught
// by the `msg.text()` in the initial `s` construction.
continue;
}
// evaluate the arg as a string by running it through the page context
s += `${await arg.evaluate(a => a.toString())} `; // trailing space is intentional
continue;
}
// Try and parse the value as an error object first (which will be an empty JSON
// object). Otherwise, parse the object to a string.
//
// Note: we have to run the checks against the object in the page context, so call
// evaluate instead of just doing it ourselves.
const stringyArg: string = await arg.evaluate((argInContext: any) => {
if (argInContext.stack || (argInContext instanceof Error)) {
// probably an error - toString it and append any properties which might not be
// caught. For example, on HTTP errors the JSON stringification will capture the
// status code.
//
// String format is a bit weird, but basically we're trying to get away from the
// stack trace so the context doesn't blend in but is otherwise indented correctly.
return `${argInContext.toString()}\n\n Error context: ${JSON.stringify(argInContext)}`;
}
// not an error, as far as we're concerned - return it as human-readable JSON
return JSON.stringify(argInContext, null, 4);
});
s += `${stringyArg} `; // trailing space is intentional
}
return s;
}