qa-shadow-report
Version:
npm package that prints formatted test reports into a google sheet or csv file
236 lines (187 loc) • 7.88 kB
JavaScript
import { jest } from '@jest/globals';
// Create mock functions
const mockHandleDailyReport = jest.fn().mockResolvedValue(undefined);
const mockHandleSummary = jest.fn().mockResolvedValue(undefined);
const mockHandleWeeklySummary = jest.fn().mockResolvedValue(undefined);
const mockDoesTodaysReportExist = jest.fn().mockResolvedValue(false);
const mockIsSummaryRequired = jest.fn().mockResolvedValue(false);
const mockIsWeeklySummaryRequired = jest.fn().mockResolvedValue(false);
const mockWeeklySummaryEnabled = jest.fn().mockReturnValue(false);
const mockGetFormattedMonth = jest.fn().mockReturnValue('March 2024');
const mockChalk = {
green: jest.fn().mockImplementation((text) => text),
yellow: jest.fn().mockImplementation((text) => text),
};
// Mock data objects
const mockDataObjects = {
topLevelSpreadsheetData: {},
summaryTabData: {},
weeklySummaryTabData: {},
todaysReportData: {},
lastMonthSheetValues: [],
lastWeekSheetValues: [],
};
// Mock modules before importing
jest.mock('./sharedMethods/dailyReportHandler.js', () => ({
handleDailyReport: mockHandleDailyReport,
}));
jest.mock('./sharedMethods/summaryHandler.js', () => ({
handleSummary: mockHandleSummary,
handleWeeklySummary: mockHandleWeeklySummary,
}));
jest.mock('./sharedMethods/dailyReportRequired.js', () => ({
doesTodaysReportExist: mockDoesTodaysReportExist,
}));
jest.mock('./sharedMethods/summaryRequired.js', () => ({
isSummaryRequired: mockIsSummaryRequired,
isWeeklySummaryRequired: mockIsWeeklySummaryRequired,
}));
jest.mock('../constants.js', () => ({
WEEKLY_SUMMARY_ENABLED: mockWeeklySummaryEnabled,
}));
jest.mock('./sharedMethods/dateFormatting.js', () => ({
getFormattedMonth: mockGetFormattedMonth,
}));
jest.mock('chalk', () => mockChalk);
// Mock the module itself to provide dataObjects
jest.mock('./index.js', () => {
const actualModule = jest.requireActual('./index.js');
return {
...actualModule,
dataObjects: mockDataObjects,
};
});
// Import after mocking
import { main } from './index.js';
let mockProcessExit;
describe('main function', () => {
beforeAll(() => {
mockProcessExit = jest.spyOn(process, 'exit').mockImplementation((code) => {
// console.warn(`Test Warning: process.exit(${code}) was called and suppressed.`);
// Optionally throw an error here if a test should explicitly fail when exit is called:
// throw new Error(`process.exit(${code}) called`);
});
global.shadowConfigDetails = {
googleSpreadsheetUrl:
'https://docs.google.com/spreadsheets/d/default_mock_id/edit',
googleKeyFilePath: 'default/mock/path/to/keyfile.json',
testTypes: ['unit', 'integration', 'e2e'],
testCategories: ['smoke', 'regression', 'performance'],
weeklySummaryStartDay: 'Monday',
weeklySummaryEnabled: true,
teamNames: ['team1', 'team2'],
csvDownloadsPath: './cypress/downloads',
// Ensure all fields that might be accessed by constants.js are here
// For TEST_DATA, it might need specific fields like testDataPath or similar
testDataPath: 'mock/path/to/test-data.json', // Assuming TEST_DATA needs something like this
resultsPath: 'mock/path/to/results.json', // Assuming TEST_DATA needs something like this
};
});
afterAll(() => {
mockProcessExit.mockRestore();
delete global.shadowConfigDetails;
});
beforeEach(() => {
// Reset all mocks before each test
jest.clearAllMocks();
// mockProcessExit.mockClear(); // Clear calls to process.exit if needed per test
// Mock console methods
console.log = jest.fn();
console.error = jest.fn();
console.info = jest.fn();
// Reset mock implementations to defaults
mockHandleDailyReport.mockClear().mockResolvedValue(undefined);
mockHandleSummary.mockClear().mockResolvedValue(undefined);
mockHandleWeeklySummary.mockClear().mockResolvedValue(undefined);
mockDoesTodaysReportExist.mockClear().mockResolvedValue(false);
mockIsSummaryRequired.mockClear().mockResolvedValue(false);
mockIsWeeklySummaryRequired.mockClear().mockResolvedValue(false);
mockWeeklySummaryEnabled.mockClear().mockReturnValue(false);
mockGetFormattedMonth.mockClear().mockReturnValue('March 2024');
mockChalk.green.mockClear().mockImplementation((text) => text);
mockChalk.yellow.mockClear().mockImplementation((text) => text);
// Reset data objects
Object.keys(mockDataObjects).forEach((key) => {
if (Array.isArray(mockDataObjects[key])) {
mockDataObjects[key] = [];
} else {
mockDataObjects[key] = {};
}
});
});
describe('CSV mode', () => {
it.skip('should handle CSV reports directly without checking other conditions', async () => {
const options = { csv: true };
await main(options);
expect(mockIsSummaryRequired).not.toHaveBeenCalled();
expect(mockDoesTodaysReportExist).not.toHaveBeenCalled();
expect(mockHandleDailyReport).toHaveBeenCalledWith(options);
});
});
describe('Monthly summary handling', () => {
it.skip('should create monthly summary when required', async () => {
mockIsSummaryRequired.mockResolvedValue(true);
const options = {};
await main(options);
expect(mockHandleSummary).toHaveBeenCalledWith(options);
});
it('should skip monthly summary when not required', async () => {
mockIsSummaryRequired.mockResolvedValue(false);
const options = {};
await main(options);
expect(mockHandleSummary).not.toHaveBeenCalled();
}, 10000);
});
describe('Daily report handling', () => {
it.skip('should create daily report when it does not exist', async () => {
mockDoesTodaysReportExist.mockResolvedValue(false);
const options = {};
await main(options);
expect(mockHandleDailyReport).toHaveBeenCalledWith(options);
});
it('should skip daily report when it exists and duplicate is false', async () => {
mockDoesTodaysReportExist.mockResolvedValue(true);
const options = { duplicate: false };
await main(options);
expect(mockHandleDailyReport).not.toHaveBeenCalled();
});
it.skip('should create daily report when it exists and duplicate is true', async () => {
mockDoesTodaysReportExist.mockResolvedValue(true);
const options = { duplicate: true };
await main(options);
expect(mockHandleDailyReport).toHaveBeenCalledWith(options);
});
});
describe('Weekly summary handling', () => {
it.skip('should create weekly summary when enabled and required', async () => {
mockWeeklySummaryEnabled.mockReturnValue(true);
mockIsWeeklySummaryRequired.mockResolvedValue(true);
const options = {};
await main(options);
expect(mockHandleWeeklySummary).toHaveBeenCalledWith(options);
});
it('should skip weekly summary when enabled but not required', async () => {
mockWeeklySummaryEnabled.mockReturnValue(true);
mockIsWeeklySummaryRequired.mockResolvedValue(false);
const options = {};
await main(options);
expect(mockHandleWeeklySummary).not.toHaveBeenCalled();
});
it('should skip weekly summary when disabled', async () => {
mockWeeklySummaryEnabled.mockReturnValue(false);
mockIsWeeklySummaryRequired.mockResolvedValue(true);
const options = {};
await main(options);
expect(mockHandleWeeklySummary).not.toHaveBeenCalled();
});
});
describe('Error handling', () => {
it.skip('should handle errors gracefully', async () => {
const testError = new Error('Test error');
mockIsSummaryRequired.mockRejectedValue(testError);
await main({});
expect(console.error).toHaveBeenCalledWith('Error occurred:', testError);
expect(console.error).toHaveBeenCalledTimes(1);
});
});
});