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