xref: /aosp_15_r20/external/pigweed/pw_web/log-viewer/test/log-list.test.js (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15import { expect } from '@open-wc/testing';
16import '../src/components/log-viewer';
17import { MockLogSource } from '../src/custom/mock-log-source';
18import { createLogViewer } from '../src/createLogViewer';
19
20describe('log-list', () => {
21  let mockLogSource;
22  let logViewer;
23
24  beforeEach(() => {
25    window.localStorage.clear();
26
27    // Initialize the log viewer component with a mock log source
28    mockLogSource = new MockLogSource();
29    logViewer = createLogViewer(mockLogSource, document.body);
30
31    // Handle benign error caused by custom log viewer initialization
32    // See: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors
33    const e = window.onerror;
34    window.onerror = function (err) {
35      if (
36        err === 'ResizeObserver loop completed with undelivered notifications.'
37      ) {
38        console.warn(
39          'Ignored: ResizeObserver loop completed with undelivered notifications.',
40        );
41        return false;
42      } else {
43        return e(...arguments);
44      }
45    };
46  });
47
48  afterEach(() => {
49    mockLogSource.stop();
50    logViewer(); // Destroy the LogViewer instance
51  });
52
53  it('displays log entry content correctly', async () => {
54    const numLogs = 5;
55    const logEntries = [];
56
57    for (let i = 0; i < numLogs; i++) {
58      const logEntry = mockLogSource.readLogEntryFromHost();
59      logEntries.push(logEntry);
60    }
61
62    const logViewer = document.querySelector('log-viewer');
63    logViewer.logs = logEntries;
64
65    // Wait for components to load
66    await logViewer.updateComplete;
67    await new Promise((resolve) => setTimeout(resolve, 200));
68
69    const logView = logViewer.shadowRoot.querySelector('log-view');
70    const logList = logView.shadowRoot.querySelector('log-list');
71    const table = logList.shadowRoot.querySelector('table');
72    const tableRows = table.querySelectorAll('tbody tr');
73
74    // Iterate through log entries and compare each one to its respective <tr> element.
75    for (let i = 0; i < numLogs; i++) {
76      const logEntry = logEntries[i];
77      const logEntryFieldsExceptLevel = logEntry.fields.filter(
78        (field) => field.key !== 'level', // Skip `level`
79      );
80      const tds = tableRows[i].querySelectorAll('td');
81
82      // Iterate through the fields and compare them to the text content of the <td> elements
83      for (let j = 0; j < logEntryFieldsExceptLevel.length; j++) {
84        const field = logEntryFieldsExceptLevel[j];
85        let tdTextContent = tds[j + 1].textContent; // Skip `level`
86
87        // Remove extraneous characters (spaces, newlines, etc.)
88        const fieldText = field.value
89          .replace(/\n/g, ' ')
90          .replace(/ +/g, ' ')
91          .trim();
92        tdTextContent = tdTextContent
93          .replace(/\n/g, ' ')
94          .replace(/ +/g, ' ')
95          .trim();
96
97        expect(tdTextContent).to.equal(fieldText);
98      }
99    }
100  });
101});
102