mirror of https://github.com/vector-im/riot-web
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.pull/21833/head
parent
f9ad2a5151
commit
75abf03fed
|
@ -19,7 +19,7 @@ import * as puppeteer from 'puppeteer';
|
|||
|
||||
import { Logger } from './logger';
|
||||
import { LogBuffer } from './logbuffer';
|
||||
import { delay } from './util';
|
||||
import { delay, serializeLog } from './util';
|
||||
|
||||
const DEFAULT_TIMEOUT = 20000;
|
||||
|
||||
|
@ -35,7 +35,7 @@ export class ElementSession {
|
|||
constructor(readonly browser: puppeteer.Browser, readonly page: puppeteer.Page, readonly username: string,
|
||||
readonly elementServer: string, readonly hsUrl: string) {
|
||||
this.consoleLog = new LogBuffer(page, "console",
|
||||
async (msg: puppeteer.ConsoleMessage) => Promise.resolve(`${msg.text()}\n`));
|
||||
async (msg: puppeteer.ConsoleMessage) => `${await serializeLog(msg)}\n`);
|
||||
this.networkLog = new LogBuffer(page,
|
||||
"requestfinished", async (req: puppeteer.HTTPRequest) => {
|
||||
const type = req.resourceType();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ async function runTests() {
|
|||
/**
|
||||
* TODO: temporary only use one user session data
|
||||
*/
|
||||
performanceEntries = JSON.parse(measurements);
|
||||
performanceEntries = JSON.parse(measurements ?? "[]");
|
||||
return session.close();
|
||||
}));
|
||||
if (performanceEntries?.length > 0) {
|
||||
|
|
Loading…
Reference in New Issue