blob: bd3850393fe49367715e001e8e0f6852cb720c4f [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import chai from 'chai'; // not esm
import chaiDom from 'chai-dom'; // not esm
import * as constant from '../src/constants';
import { FakeWebviewAPi, ffxEventForTest, logDataForTest, malformedLogForTest }
from './util';
import { Filter } from '../src/filter';
import { LogList, WRAP_LOG_TEXT_ATTR } from '../components/log_list';
import { State } from '../src/state';
import {LitElement} from 'lit';
before(function () {
chai.should();
chai.use(chaiDom);
});
describe('LogList', () => {
let root: HTMLElement;
let state: State;
beforeEach(() => {
root = document.createElement('div');
document.body.appendChild(root);
state = new State(new FakeWebviewAPi());
});
afterEach(() => {
root.remove();
});
describe('#constructor', () => {
it('crates a new empty view', () => {
const logsList = new LogList(state);
logsList.element.children.length.should.equal(1);
logsList.element.children[0].id.should.equal('logs-table-header');
});
it('sets the log wrapping from the state', () => {
state.shouldWrapLogs = true;
let logList = new LogList(state);
logList.element.hasAttribute(WRAP_LOG_TEXT_ATTR).should.be.true;
state.shouldWrapLogs = false;
logList = new LogList(state);
logList.element.hasAttribute(WRAP_LOG_TEXT_ATTR).should.be.false;
});
});
describe('#addLog', () => {
it('appends a log', async () => {
const view = new LogList(state);
const logsList = view.element;
document.body.appendChild(logsList);
logsList.children.length.should.equal(1);
logsList.children[0].id.should.equal('logs-table-header');
view.addLog(logDataForTest('core/foo'));
logsList.children.length.should.equal(2);
const logLine = logsList.children[1] as LitElement;
await logLine.updateComplete;
logLine.children[0].should.have.class('log-entry');
logLine.children[0].should.have.attr('data-moniker', 'core/foo');
logLine.children[0].should.have.attr('data-pid', '123');
logLine.children[0].should.have.attr('data-tid', '456');
(logLine.children[0] as HTMLElement).hidden.should.be.false;
const testFields = ['000000.12', '123', '456', 'core/foo', 'my_tag', 'Info', 'msg'];
let field: keyof typeof testFields;
for (field in testFields) {
const logField = logLine.children[0].children[field] as HTMLElement;
logField.innerText.should.equal(testFields[field]);
}
logsList.remove();
});
it('hides the log if the filters require so', () => {
const view = new LogList(state);
state.registerFilter(new Filter({
category: 'moniker',
subCategory: undefined,
operator: 'contains',
value: 'core/bar',
}), 'moniker:core/bar');
view.addLog(logDataForTest('core/foo'));
const logsList = view.element;
logsList.children.length.should.equal(2);
const logLine = logsList.children[1] as HTMLElement;
logLine.hidden.should.be.true;
});
it('handles ffx events', async () => {
const view = new LogList(state);
let moniker = constant.FFX_MONIKER;
const msg = 'Logger lost connection to target. Retrying...';
view.addLog(ffxEventForTest('TargetDisconnected'));
const logsList = view.element;
document.body.appendChild(logsList);
logsList.children.length.should.equal(2);
logsList.children[0].id.should.equal('logs-table-header');
const logLine = logsList.children[1] as LitElement;
await logLine.updateComplete;
logLine.children[0].children.length.should.equal(7);
logLine.children[0].should.have.class('log-entry');
logLine.children[0].should.have.attr('data-moniker', '<ffx>');
(logLine.children[0] as HTMLElement).hidden.should.be.false;
let monikerEl = logLine.children[0].children[3] as HTMLElement;
let msgEl = logLine.children[0].children[6] as HTMLElement;
monikerEl.innerText.should.equal(moniker);
msgEl.innerText.should.equal(msg);
logsList.remove();
});
it('handles malformed logs', async () => {
const view = new LogList(state);
const msg = 'Malformed target log: oh no something went wrong';
view.addLog(malformedLogForTest('oh no something went wrong'));
const logsList = view.element;
document.body.appendChild(logsList);
logsList.children.length.should.equal(2);
logsList.children[0].id.should.equal('logs-table-header');
const logLine = logsList.children[1] as LitElement;
await logLine.updateComplete;
logLine.children[0].children.length.should.equal(7);
logLine.children[0].should.have.class('log-entry');
(logLine.children[0] as HTMLElement).hidden.should.be.false;
let msgEl = logLine.children[0].children[6] as HTMLElement;
msgEl.innerText.should.equal(msg);
logsList.remove();
});
it('detects user hovering logs', () => {
const view = new LogList(state);
view.addLog(logDataForTest('core/foo'));
const scrollArea = view.element.parentElement;
scrollArea?.matches(':hover').should.equal(false);
scrollArea?.dispatchEvent(new MouseEvent('onmouseenter'));
scrollArea?.matches(':hover').should.equal(true);
});
});
describe('#reset', () => {
it('resets the log list', () => {
const view = new LogList(state);
view.addLog(logDataForTest('core/foo'));
let logsList = view.element;
logsList.children.length.should.equal(2);
view.reset();
logsList.children.length.should.equal(1);
});
});
});