commit
a421bf213e
48 changed files with 1571 additions and 147 deletions
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -40,6 +40,7 @@
|
|||
"@vue/cli-service": "~5.0.0",
|
||||
"@vue/test-utils": "^2.4.1",
|
||||
"@vue/vue3-jest": "^27.0.0-alpha.1",
|
||||
"axe-core": "^4.10.2",
|
||||
"axios": "^1.7.8",
|
||||
"axios-mock-adapter": "^1.21.5",
|
||||
"babel-jest": "^27.0.6",
|
||||
|
|
@ -6039,6 +6040,16 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/axe-core": {
|
||||
"version": "4.10.2",
|
||||
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz",
|
||||
"integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==",
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.9",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
"vite": "^4.5.9",
|
||||
"vitest": "^0.33.0",
|
||||
"volar-service-vetur": "latest",
|
||||
"wait-on": "^8.0.2"
|
||||
"wait-on": "^8.0.2",
|
||||
"axe-core": "^4.10.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,17 @@ CCIS_API_AUTH=
|
|||
|
||||
# DEV
|
||||
BASE_URL="https://selfservice.dev.glassclaim.com"
|
||||
CCIS_API_URL="https://api.dev.belronus.io"
|
||||
CCIS_API_URL="https://api.test.belronus.io" # Test API connects to our DEV environments for some reason
|
||||
ADMIN_SERVICE_API_URL="https://issadminapi.dev.sagaws.net/iss-admin/api/v1/"
|
||||
DIGITAL_API_URL="https://digitalapi.dev.safelite.io"
|
||||
ENABLE_ACCESSIBILITY_TESTING = true
|
||||
ENABLE_MOCK_TESTING = false
|
||||
|
||||
|
||||
# QA
|
||||
# BASE_URL="https://selfservice.test.glassclaim.com"
|
||||
# CCIS_API_URL="https://api.test.belronus.io"
|
||||
# CCIS_API_URL="https://api.test.belronus.io"
|
||||
# ADMIN_SERVICE_API_URL="https://issadminapi.test.sagaws.net/iss-admin/api/v1/"
|
||||
# DIGITAL_API_URL="https://digitalapi.test.safelite.io"
|
||||
# ENABLE_ACCESSIBILITY_TESTING = true
|
||||
# ENABLE_MOCK_TESTING = false
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -30,9 +30,9 @@ export interface IVehicleDetails {
|
|||
make: string,
|
||||
model: string,
|
||||
style?: string,
|
||||
vin?: string,
|
||||
licensePlateNumber?: string,
|
||||
licensePlateState?: string,
|
||||
vin?: string|string[],
|
||||
licensePlateNumber?: string|string[],
|
||||
licensePlateState?: string|string[],
|
||||
vehicleLookupType?: VehicleLookupType,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export interface ITestData {
|
|||
isDuplicateClaim: boolean,
|
||||
isPolicyFound: boolean, // Effective difference between advanced and essential
|
||||
isUseVehicleOnPolicy: boolean, // Should we use the vehicle on the policy?
|
||||
isVehicleLookupValidations: boolean, // Should we validate vehicle lookup?
|
||||
isNoComp: boolean, // Is this a NoComp policy?
|
||||
isItac: boolean, // Is this an ITAC scenario?
|
||||
hasStateLawPopup: boolean, // Are we expecting a state law pop-up on ProviderSelectionPage?
|
||||
|
|
|
|||
|
|
@ -135,7 +135,9 @@ export default class TestCase extends DisposableBase implements ITestCase {
|
|||
|
||||
|
||||
if (testInfo.testCase)
|
||||
await testInfo.testCase.disposeAll();
|
||||
if (!(testInfo.testCase.testData!.isMockTesting ?? false)) {
|
||||
await testInfo.testCase.disposeAll();
|
||||
}
|
||||
|
||||
const seconds: string = String(testInfo.duration / 1000);
|
||||
const minutes: string = (testInfo.duration / 1000 / 60).toFixed(2);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,154 @@
|
|||
import { Page } from '@playwright/test';
|
||||
import { type AxiosInstance, type AxiosResponse } from 'axios';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Page } from 'playwright';
|
||||
import { AxiosResponse, AxiosInstance } from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
interface MockResponse {
|
||||
status: number;
|
||||
body: any;
|
||||
headers?: { [key: string]: string };
|
||||
}
|
||||
|
||||
class MockApiManager {
|
||||
private static instance: MockApiManager;
|
||||
private mockResponses: { [url: string]: MockResponse } = {};
|
||||
private constructor() { }
|
||||
public static referralNumber: string;
|
||||
public static referralSequenceNumber: string;
|
||||
public static referralCorrelationId: string;
|
||||
public static savedSessionId: string;
|
||||
|
||||
public static getInstance(): MockApiManager {
|
||||
if (!MockApiManager.instance) {
|
||||
MockApiManager.instance = new MockApiManager();
|
||||
}
|
||||
return MockApiManager.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads mock responses from a configuration file.
|
||||
* @param scenario - The scenario to load mock responses for.
|
||||
*/
|
||||
private loadMockResponses(scenario: string): void {
|
||||
const mockResponsesDir = path.resolve(__dirname, '../../tests/mockResponses');
|
||||
const configFilePath = path.join(mockResponsesDir, 'mockResponsesConfig.json');
|
||||
|
||||
if (fs.existsSync(configFilePath)) {
|
||||
const config = JSON.parse(fs.readFileSync(configFilePath, 'utf-8'));
|
||||
const scenarioConfig = config[scenario];
|
||||
const commonConfig = config['common'];
|
||||
|
||||
for (const endpoint in scenarioConfig) {
|
||||
this.loadMockResponse(endpoint, scenarioConfig[endpoint], mockResponsesDir);
|
||||
}
|
||||
|
||||
for (const endpoint in commonConfig) {
|
||||
if (!this.mockResponses[endpoint]) {
|
||||
this.loadMockResponse(endpoint, commonConfig[endpoint], mockResponsesDir);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error(`Mock responses configuration file not found at path: ${configFilePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a single mock response from a file.
|
||||
* @param endpoint - The endpoint to load the mock response for.
|
||||
* @param mockFilePath - The path to the mock response file.
|
||||
* @param mockResponsesDir - The directory containing the mock response files.
|
||||
*/
|
||||
private loadMockResponse(endpoint: string, mockFilePath: string, mockResponsesDir: string): void {
|
||||
const filePath = path.join(mockResponsesDir, mockFilePath);
|
||||
if (fs.existsSync(filePath)) {
|
||||
const mockResponse = fs.readFileSync(filePath, 'utf-8');
|
||||
try {
|
||||
this.mockResponses[endpoint] = JSON.parse(mockResponse);
|
||||
} catch (error) {
|
||||
console.error(`Error parsing mock response for endpoint: ${endpoint}`, error);
|
||||
}
|
||||
} else {
|
||||
console.warn(`Mock response file${filePath} not found for endpoint: ${endpoint}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mocked API response for the given endpoint.
|
||||
* @param endpoint - The endpoint to get the mocked response for.
|
||||
* @param scenario - The scenario to load mock responses for.
|
||||
* @returns The mocked response or null if not found.
|
||||
*/
|
||||
public getMockedApiResponse(endpoint: string, scenario: string): MockResponse | null {
|
||||
if (!this.mockResponses[endpoint]) {
|
||||
this.loadMockResponses(scenario);
|
||||
}
|
||||
return this.mockResponses[endpoint] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks the API response for the given endpoint.
|
||||
* @param page - The Playwright page object.
|
||||
* @param endpoint - The endpoint to mock.
|
||||
* @param scenario - The scenario to load mock responses for.
|
||||
* @param mockTestingFlag - Flag to enable or disable mocking.
|
||||
*/
|
||||
public async mockApiResponse(page: Page, scenario: string, mockTestingFlag: boolean): Promise<void> {
|
||||
if (!mockTestingFlag) {
|
||||
console.info("mockTestingFlag is false/undefined. so proceeding with original requests.")
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scenario) {
|
||||
console.error('Invalid scenario provided for mocking.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadMockResponses(scenario);
|
||||
|
||||
for (const endpoint in this.mockResponses) {
|
||||
await page.route(`**/${endpoint}`, async (route) => {
|
||||
const response = this.mockResponses[endpoint];
|
||||
|
||||
if (response) {
|
||||
route.fulfill({
|
||||
status: response.status || 200,
|
||||
body: JSON.stringify(response.body || response),
|
||||
headers: response.headers || { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
console.info("Mocking Endpoint: " + endpoint)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async updateReferralDetails(endpoint: string, response: MockResponse): Promise<MockResponse> {
|
||||
try {
|
||||
response.body.referralCorrelationId = MockApiManager.referralCorrelationId;
|
||||
response.body.referralNumber = MockApiManager.referralNumber;
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
public async getReferralDetails(endpoint: string, response: MockResponse) {
|
||||
if (endpoint.includes('order/save-session/iss')) {
|
||||
MockApiManager.referralNumber = response.body.referralNumber;
|
||||
MockApiManager.referralSequenceNumber = response.body.referralSequenceNumber;
|
||||
MockApiManager.referralCorrelationId = response.body.referralCorrelationId;
|
||||
MockApiManager.savedSessionId = response.body.sessionId;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Export the instance
|
||||
export const mockApiManager = MockApiManager.getInstance();
|
||||
|
||||
export async function httpGet<T>(client: AxiosInstance, url: string): Promise<T> {
|
||||
const [isSuccess, response] = await handleHttp(client.get<T>(url));
|
||||
if(isSuccess) {
|
||||
if (isSuccess) {
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
@ -15,7 +158,7 @@ export async function httpGet<T>(client: AxiosInstance, url: string): Promise<T>
|
|||
|
||||
export async function httpPost<T, D>(client: AxiosInstance, url: string, data: D): Promise<T> {
|
||||
const [isSuccess, response] = await handleHttp(client.post<T>(url, data));
|
||||
if(isSuccess) {
|
||||
if (isSuccess) {
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
@ -47,46 +190,3 @@ export function forceAPIError(page: Page, endpoint: string) {
|
|||
: route.continue()
|
||||
});
|
||||
}
|
||||
|
||||
// Utility method to return mock response based on endpoint and scenario
|
||||
export function getMockedApiResponse(endpoint: string, scenario: string): object | null {
|
||||
const mockResponsesDir = path.resolve(__dirname, '../../tests/mockResponses');
|
||||
const configFilePath = path.join(mockResponsesDir, 'mockResponsesConfig.json');
|
||||
|
||||
if (fs.existsSync(configFilePath)) {
|
||||
const config = JSON.parse(fs.readFileSync(configFilePath, 'utf-8'));
|
||||
const scenarioConfig = config[scenario];
|
||||
const commonConfig = config['common'];
|
||||
|
||||
let mockFilePath = scenarioConfig ? scenarioConfig[endpoint] : null;
|
||||
if (!mockFilePath && commonConfig) {
|
||||
mockFilePath = commonConfig[endpoint];
|
||||
}
|
||||
|
||||
if (mockFilePath) {
|
||||
const filePath = path.join(mockResponsesDir, mockFilePath);
|
||||
if (fs.existsSync(filePath)) {
|
||||
const mockResponse = fs.readFileSync(filePath, 'utf-8');
|
||||
return JSON.parse(mockResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Utility method for mocking API responses
|
||||
export function mockApiResponse(page: Page, endpoint: string, scenario: string, mockTestingFlag: boolean) {
|
||||
const mockResponse = getMockedApiResponse(endpoint, scenario);
|
||||
page.route(`**/${endpoint}`, route => {
|
||||
if (mockResponse && mockTestingFlag) {
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockResponse)
|
||||
});
|
||||
} else {
|
||||
route.continue();
|
||||
}
|
||||
});
|
||||
}
|
||||
337
playwright-tests/impl/utils/ReportUtils.ts
Normal file
337
playwright-tests/impl/utils/ReportUtils.ts
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { jsonReportFilePath, reportFilePath } from '../../playwright.config';
|
||||
|
||||
interface PageSummary {
|
||||
pageName: string;
|
||||
critical: number;
|
||||
serious: number;
|
||||
moderate: number;
|
||||
minor: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export function updateAccessibilityReport(pageName: string, results: any) {
|
||||
const reportDir = path.dirname(jsonReportFilePath);
|
||||
if (!fs.existsSync(reportDir)) {
|
||||
fs.mkdirSync(reportDir, { recursive: true });
|
||||
}
|
||||
|
||||
let existingIssues: { [key: string]: any[] } = {};
|
||||
if (fs.existsSync(jsonReportFilePath)) {
|
||||
existingIssues = JSON.parse(fs.readFileSync(jsonReportFilePath, 'utf-8'));
|
||||
}
|
||||
|
||||
if (!existingIssues[pageName]) {
|
||||
existingIssues[pageName] = [];
|
||||
}
|
||||
|
||||
results.violations.forEach(violation => {
|
||||
const violationWithPage = { ...violation, pageName };
|
||||
if (!isDuplicateIssue(existingIssues[pageName], violationWithPage)) {
|
||||
existingIssues[pageName].push(violationWithPage);
|
||||
}
|
||||
});
|
||||
|
||||
fs.writeFileSync(jsonReportFilePath, JSON.stringify(existingIssues, null, 2));
|
||||
}
|
||||
|
||||
export function consolidateJsonReport() {
|
||||
if (!fs.existsSync(jsonReportFilePath)) {
|
||||
console.error('JSON report file does not exist.');
|
||||
return;
|
||||
}
|
||||
|
||||
const existingIssues = JSON.parse(fs.readFileSync(jsonReportFilePath, 'utf-8'));
|
||||
|
||||
// Consolidate issues by page
|
||||
const consolidatedIssues: { [key: string]: any[] } = {};
|
||||
Object.keys(existingIssues).forEach(pageName => {
|
||||
if (!consolidatedIssues[pageName]) {
|
||||
consolidatedIssues[pageName] = [];
|
||||
}
|
||||
existingIssues[pageName].forEach(issue => {
|
||||
if (!isDuplicateIssue(consolidatedIssues[pageName], issue)) {
|
||||
consolidatedIssues[pageName].push(issue);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
fs.writeFileSync(jsonReportFilePath, JSON.stringify(consolidatedIssues, null, 2));
|
||||
}
|
||||
|
||||
function generateSummaryTable(existingIssues: { [key: string]: any[] }): string {
|
||||
return `
|
||||
<table class="summary-table" role="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Page Name</th>
|
||||
<th>Critical</th>
|
||||
<th>Serious</th>
|
||||
<th>Moderate</th>
|
||||
<th>Minor</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${Object.keys(existingIssues).map(pageName => {
|
||||
const issues = existingIssues[pageName];
|
||||
const critical = issues.filter(issue => issue.impact === 'critical').length;
|
||||
const serious = issues.filter(issue => issue.impact === 'serious').length;
|
||||
const moderate = issues.filter(issue => issue.impact === 'moderate').length;
|
||||
const minor = issues.filter(issue => issue.impact === 'minor').length;
|
||||
const total = issues.length;
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td><a href="#${pageName.replace(/\s+/g, '-')}">${pageName}</a></td>
|
||||
<td><a href="#${pageName.replace(/\s+/g, '-')}-critical">${critical}</a></td>
|
||||
<td><a href="#${pageName.replace(/\s+/g, '-')}-serious">${serious}</a></td>
|
||||
<td><a href="#${pageName.replace(/\s+/g, '-')}-moderate">${moderate}</a></td>
|
||||
<td><a href="#${pageName.replace(/\s+/g, '-')}-minor">${minor}</a></td>
|
||||
<td>${total}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
function generateImpactSections(issues: any[], pageName: string): string {
|
||||
return ['critical', 'serious', 'moderate', 'minor'].map(impactType => {
|
||||
const violations = issues.filter(issue => issue.impact === impactType);
|
||||
if (violations.length === 0) return '';
|
||||
|
||||
return `
|
||||
<div class="impact-section" id="${pageName.replace(/\s+/g, '-')}-${impactType}">
|
||||
<h3>${impactType.charAt(0).toUpperCase() + impactType.slice(1)} Impact</h3>
|
||||
<button type="button" class="collapsible">${impactType.charAt(0).toUpperCase() + impactType.slice(1)} Impact</button>
|
||||
<div class="content">
|
||||
<table role="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Impact</th>
|
||||
<th>Description</th>
|
||||
<th>Help URL</th>
|
||||
<th>Tags</th>
|
||||
<th>Nodes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${violations.map(violation => `
|
||||
<tr>
|
||||
<td>${violation.impact}</td>
|
||||
<td>${violation.description}</td>
|
||||
<td><a href="${violation.helpUrl}" target="_blank">${violation.helpUrl}</a></td>
|
||||
<td>${violation.tags.join(', ')}</td>
|
||||
<td>
|
||||
${violation.nodes.map(node => `
|
||||
<div class="node">
|
||||
<div class="html">${node.html}</div>
|
||||
<div class="target">Target: ${node.target.join(', ')}</div>
|
||||
<div class="failureSummary">${node.failureSummary}</div>
|
||||
<div class="any">
|
||||
<strong>Any:</strong>
|
||||
${node.any.map(check => `
|
||||
<div class="check">
|
||||
<div class="message">${check.message}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
<div class="all">
|
||||
<strong>All:</strong>
|
||||
${node.all.map(check => `
|
||||
<div class="check">
|
||||
<div class="message">${check.message}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
<div class="none">
|
||||
<strong>None:</strong>
|
||||
${node.none.map(check => `
|
||||
<div class="check">
|
||||
<div class="message">${check.message}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</td>
|
||||
</tr>
|
||||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function generateDetailedSections(existingIssues: { [key: string]: any[] }): string {
|
||||
return Object.keys(existingIssues).map(pageName => {
|
||||
const issues = existingIssues[pageName];
|
||||
const impactSections = generateImpactSections(issues, pageName);
|
||||
|
||||
return `
|
||||
<div class="page-section" id="${pageName.replace(/\s+/g, '-')}">
|
||||
<h2>${pageName}</h2>
|
||||
${impactSections}
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
export function createAccessibilityHtmlReport() {
|
||||
consolidateJsonReport();
|
||||
|
||||
if (!fs.existsSync(jsonReportFilePath)) {
|
||||
console.error('JSON report file does not exist.');
|
||||
return;
|
||||
}
|
||||
|
||||
const existingIssues = JSON.parse(fs.readFileSync(jsonReportFilePath, 'utf-8'));
|
||||
|
||||
const inlineStyles = `
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f4f4f4;
|
||||
color: #333;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #4CAF50;
|
||||
}
|
||||
.summary-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.summary-table th, .summary-table td {
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
text-align: left;
|
||||
}
|
||||
.summary-table th {
|
||||
background-color: #007BFF;
|
||||
color: white;
|
||||
}
|
||||
.summary-table td a {
|
||||
color: #007BFF;
|
||||
text-decoration: none;
|
||||
}
|
||||
.summary-table td a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.page-section {
|
||||
margin-bottom: 40px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.impact-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.violation {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.violation .impact {
|
||||
font-weight: bold;
|
||||
color: #d9534f;
|
||||
}
|
||||
.violation .description {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.violation .helpUrl {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.violation .tags {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.violation .nodes {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.violation .node {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.collapsible {
|
||||
background-color: #f9f9f9;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
.active, .collapsible:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
.content {
|
||||
padding: 0 18px;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
th, td {
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
text-align: left;
|
||||
}
|
||||
`;
|
||||
|
||||
let reportContent = `
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>ISS Accessibility Report</title>
|
||||
<style>${inlineStyles}</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Accessibility Report</h1>
|
||||
`;
|
||||
|
||||
reportContent += generateSummaryTable(existingIssues);
|
||||
reportContent += generateDetailedSections(existingIssues);
|
||||
|
||||
reportContent += `
|
||||
<script>
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
for (var i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function() {
|
||||
this.classList.toggle("active");
|
||||
var content = this.nextElementSibling;
|
||||
if (content.style.display === "block") {
|
||||
content.style.display = "none";
|
||||
} else {
|
||||
content.style.display = "block";
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
try {
|
||||
fs.writeFileSync(reportFilePath, reportContent);
|
||||
console.log(`Accessibility Report generated successfully at ${reportFilePath}`);
|
||||
} catch (error) {
|
||||
console.error('Error writing report file:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function isDuplicateIssue(existingIssues: any[], newIssue: any): boolean {
|
||||
return existingIssues.some(issue => {
|
||||
return issue.id === newIssue.id && issue.pageName === newIssue.pageName;
|
||||
});
|
||||
}
|
||||
|
|
@ -1,4 +1,13 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import test, { expect, type Locator, type Page } from '@playwright/test';
|
||||
import axe from 'axe-core';
|
||||
import { updateAccessibilityReport } from '@utils/ReportUtils';
|
||||
import { error } from 'console';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
axe: typeof axe;
|
||||
}
|
||||
}
|
||||
|
||||
export class BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -6,15 +15,17 @@ export class BasePage {
|
|||
readonly pageSpinner: Locator;
|
||||
readonly buttonLoadSpin: Locator;
|
||||
|
||||
constructor(page: Page){
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.continueButton = page.locator('[id="infoBox"]').getByRole('button');
|
||||
this.pageSpinner = page.getByRole('status');
|
||||
this.buttonLoadSpin = page.getByRole('alert');
|
||||
}
|
||||
|
||||
|
||||
async nextPage() {
|
||||
const startingUrl = this.page.url();
|
||||
let pageName = startingUrl.split('Page=')[1] || startingUrl;
|
||||
await this.validateAccessibility(pageName);
|
||||
await expect(async () => {
|
||||
const currentUrl = this.page.url();
|
||||
if (currentUrl === startingUrl) {
|
||||
|
|
@ -26,16 +37,82 @@ export class BasePage {
|
|||
}).toPass({ timeout: 240_000 });
|
||||
}
|
||||
|
||||
async validateURL(url:string){
|
||||
await expect(this.pageSpinner).toHaveCount(0, {timeout: 60000});
|
||||
async validateURL(url: string) {
|
||||
await expect(this.pageSpinner).toHaveCount(0, { timeout: 60000 });
|
||||
await this.page.waitForURL(url);
|
||||
}
|
||||
|
||||
async fillAndValidate(element: Locator, value: string){
|
||||
async fillAndValidate(element: Locator, value: string) {
|
||||
await expect(async () => {
|
||||
await element.clear();
|
||||
await element.fill(value);
|
||||
await expect(element).toHaveValue(value);
|
||||
}).toPass();
|
||||
}
|
||||
|
||||
async validateAccessibility(pageName: string) {
|
||||
try {
|
||||
if (process.env.ENABLE_ACCESSIBILITY_TESTING !== 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Inject axe-core script into the page
|
||||
await this.page.addScriptTag({ content: axe.source });
|
||||
|
||||
// Run axe-core accessibility checks
|
||||
const results = await this.page.evaluate(async () => {
|
||||
return await window.axe.run();
|
||||
});
|
||||
|
||||
// Attach the results to the test report
|
||||
test.info().attach(`Accessibility results for ${pageName}`, {
|
||||
body: JSON.stringify(results, null, 2),
|
||||
contentType: 'application/json'
|
||||
});
|
||||
|
||||
// Update the HTML report with the findings
|
||||
updateAccessibilityReport(pageName, results);
|
||||
} catch (error) {
|
||||
console.warn(`Error running accessibility checks for ${pageName}: ${error}`);
|
||||
}
|
||||
}
|
||||
async clickWithRetry(element, page) {
|
||||
const timeout = 5000; // milli seconds
|
||||
const startTime = Date.now();
|
||||
while (Date.now() - startTime < timeout) {
|
||||
try {
|
||||
if (await element.isEnabled()) {
|
||||
await element.click();
|
||||
await element.keyboard.press('Tab');
|
||||
return; // Exit loop if click succeeds
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore error and retry
|
||||
}
|
||||
await page.waitForTimeout(100); // Small delay before retrying
|
||||
}
|
||||
console.log(`Failed to click the the element within ${timeout/1000} seconds` + error);
|
||||
}
|
||||
|
||||
async logReferralNumber() {
|
||||
let mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||
let referralNumber = mainLocalStorage.order.referralNumber as number;
|
||||
let referralSequenceNumber = mainLocalStorage.order.referralSequenceNumber as number;
|
||||
if (referralNumber == null) {
|
||||
for (let i = 1; i <= 20; i++) {
|
||||
if (!referralNumber == null) break;
|
||||
await this.page.waitForTimeout(500);
|
||||
mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||
referralNumber = mainLocalStorage.order.referralNumber as number;
|
||||
referralSequenceNumber = mainLocalStorage.order.referralSequenceNumber as number;
|
||||
}
|
||||
}
|
||||
|
||||
await test.step(`Referral Number:${referralNumber} Referral Sequence Number:${referralSequenceNumber}`, async () => {
|
||||
console.log(`Referral Number:${referralNumber}`);
|
||||
console.log(`Referral Sequence Number:${referralSequenceNumber}`);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ export class OrderConfirmationPage extends BasePage {
|
|||
async validateOrderConfirmationPage(testData: Partial<ITestData>) {
|
||||
// Destructure data we use
|
||||
const { vehicleDetails, customerDetails, servicePackage, isItac,
|
||||
isNoComp, isPolicyFound, claimDetails, paymentDetails } = testData;
|
||||
isNoComp, isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy } = testData;
|
||||
await this.serviceText.waitFor({ state: "visible" });
|
||||
await this.logOrderNumber();
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ export class OrderConfirmationPage extends BasePage {
|
|||
expect.soft(servicePackageAmt).toBeGreaterThan(0);
|
||||
}
|
||||
|
||||
if (isPolicyFound) {
|
||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true)) {
|
||||
// Extract numbers
|
||||
const amountDueAmt = Number.parseFloat(amountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||
const deductibleAmt = deductibleTextValue? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')): 0;
|
||||
|
|
|
|||
|
|
@ -24,12 +24,13 @@ export class PartQuestionsPage extends BasePage {
|
|||
|
||||
async selectPartQuestionResponses(partQuestions: IPartQuestion[]) {
|
||||
for (const pq of partQuestions) {
|
||||
const partQuestionOptionButton = this.page.locator(`fieldset[aria-labelledby="${pq.partQuestionType}"]`).locator(`[buttonlabel="${pq.optionToSelect}"]`);
|
||||
const parentobject=this.page.locator(`fieldset[aria-labelledby="${pq.partQuestionType}"]`);
|
||||
const partQuestionOptionButton = parentobject.locator(`[buttonlabel="${pq.optionToSelect}"]`);
|
||||
await partQuestionOptionButton.click();
|
||||
if (pq.secondaryQuestionOptionToSelect != null) {
|
||||
const secondaryQuestionButton = this.page.getByText(`${pq.secondaryQuestionOptionToSelect}`);
|
||||
secondaryQuestionButton.click();
|
||||
const secondaryQuestionButton = parentobject.getByText(`${pq.secondaryQuestionOptionToSelect}`);
|
||||
await secondaryQuestionButton.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { PaypalPage } from './PaypalPage';
|
|||
export class PaymentMethodPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly payAtServiceButton: Locator;
|
||||
readonly havePaymentReadyMsg: Locator;
|
||||
readonly payNowButton: Locator;
|
||||
readonly payInFourButton: Locator;
|
||||
readonly paypalButton: Locator;
|
||||
|
|
@ -20,6 +21,7 @@ export class PaymentMethodPage extends BasePage {
|
|||
super(page);
|
||||
this.page = page;
|
||||
this.payAtServiceButton = this.page.locator('[buttonlabel="Pay at my appointment"]'); //this.page.getByText('Pay at time of service');
|
||||
this.havePaymentReadyMsg = this.page.getByText('Please have payment ready during your appointment.'); // it will be displayed when there is no payment option
|
||||
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]');
|
||||
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]');
|
||||
this.paypalButton = this.page.frameLocator('iframe[name="card-frame"]').locator('div[id="paypalParentDiv"]');
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ export class TpaSearchPage extends BasePage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.firstLocationButton = page.locator("fieldset[aria-labelledby='chooseShop']").first();
|
||||
// this.firstLocationButton = page.locator("fieldset[aria-labelledby='chooseShop']/span").first();
|
||||
this.firstLocationButton = page.locator("#buttonLabelSpan").first();
|
||||
|
||||
this.doNotSeeMyShopButton = page.getByRole('link', { name: 'I don\'t see my shop' });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
|
||||
|
|
@ -6,17 +6,34 @@ export class VehicleLookupLicensePage extends BasePage {
|
|||
readonly page: Page;
|
||||
readonly licensePlateNumTextBox: Locator;
|
||||
readonly licensePlateStateDrpDwn: Locator;
|
||||
readonly plateNoMatchError: Locator;
|
||||
readonly plateMismatchAlert: Locator;
|
||||
url = process.env['BASE_URL']! + '/?issPage='; // TODO: Input correct URL
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.licensePlateNumTextBox = page.getByRole('textbox', { name: 'License plate number'});
|
||||
this.licensePlateStateDrpDwn = page.getByRole('combobox', { name: 'License plate state'});
|
||||
this.licensePlateNumTextBox = page.getByRole('textbox', { name: 'License plate number' });
|
||||
this.licensePlateStateDrpDwn = page.getByRole('combobox', { name: 'License plate state' });
|
||||
this.plateNoMatchError = page.getByText('Your license plate didn’t return a VIN match.Please re-enter the information');
|
||||
this.plateMismatchAlert = page.getByRole('alert').locator('div');
|
||||
}
|
||||
|
||||
async enterPlateDetails(vehicleDetails: IVehicleDetails){
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber || '');
|
||||
async enterPlateDetails(vehicleDetails: IVehicleDetails, isVehicleLookupValidations = false) {
|
||||
if (Array.isArray(vehicleDetails.licensePlateNumber)) {
|
||||
if (isVehicleLookupValidations) {
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[0]);
|
||||
await this.continueButton.click({ timeout: 1000 });
|
||||
await expect(this.plateNoMatchError).toBeVisible();
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[1]);
|
||||
await this.continueButton.click({ timeout: 1000 });
|
||||
await expect(this.plateMismatchAlert).toBeVisible();
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[2]);
|
||||
}
|
||||
|
||||
} else {
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber || '');
|
||||
}
|
||||
await this.licensePlateStateDrpDwn.selectOption(vehicleDetails.licensePlateState!);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
|
||||
|
|
@ -25,11 +25,18 @@ export class VehicleSelectionPage extends BasePage {
|
|||
await this.yearDropdown.selectOption(vehicleDetails.year);
|
||||
await this.yearDropdown.press('Tab');
|
||||
await this.makeDropdown.selectOption(vehicleDetails.make);
|
||||
await this.yearDropdown.press('Tab');
|
||||
await expect(this.modelDropdown).toBeEditable({ timeout: 5000 });
|
||||
await this.makeDropdown.press('Tab');
|
||||
await this.modelDropdown.selectOption(vehicleDetails.model);
|
||||
await this.yearDropdown.press('Tab');
|
||||
if (vehicleDetails.style != undefined) {
|
||||
await expect(this.styleDropdown).toBeEditable({ timeout: 2000 });
|
||||
await this.modelDropdown.press('Tab');
|
||||
if (vehicleDetails.style) {
|
||||
await this.styleDropdown.selectOption(vehicleDetails.style);
|
||||
} else {
|
||||
if (await this.styleDropdown.inputValue() === 'Select an option') {
|
||||
await this.styleDropdown.selectOption({ index: 1 })
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import test, { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class VinLookupPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly vinLookupTextBox: Locator;
|
||||
readonly lookupVinForMe: Locator;
|
||||
readonly vinMismatchAlert: Locator;
|
||||
url = process.env['BASE_URL']! + '/?issPage=vin-lookup'; // TODO: Input correct URL
|
||||
|
||||
constructor(page: Page) {
|
||||
|
|
@ -12,11 +13,26 @@ export class VinLookupPage extends BasePage {
|
|||
this.page = page;
|
||||
this.vinLookupTextBox = page.getByRole('textbox', { name: 'Enter your VIN' });
|
||||
this.lookupVinForMe = page.getByRole('link', { name: 'look up your VIN' });
|
||||
this.vinMismatchAlert = page.getByLabel('vehicle-not-matched-alert');
|
||||
// this.validateURL(this.url);
|
||||
}
|
||||
|
||||
async enterVin(vin: string) {
|
||||
await this.vinLookupTextBox.fill(vin);
|
||||
async enterVin(vin: string | string[], isVehicleLookupValidations = false) {
|
||||
if (Array.isArray(vin)) {
|
||||
if (vin.length > 1) {
|
||||
if (isVehicleLookupValidations) {
|
||||
await this.vinLookupTextBox.fill(vin[0]);
|
||||
await this.continueButton.click({ timeout: 1000 });
|
||||
await expect(this.vinMismatchAlert).toBeVisible();
|
||||
await this.vinLookupTextBox.fill(vin[1]);
|
||||
}
|
||||
} else {
|
||||
console.warn("VIN array is blank. Either provide VIN as string or string[]")
|
||||
}
|
||||
|
||||
} else {
|
||||
await this.vinLookupTextBox.fill(vin);
|
||||
}
|
||||
}
|
||||
|
||||
async triggerBailout() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { defineConfig, devices } from '@playwright/test';
|
||||
import dotenv from 'dotenv-safe';
|
||||
import { OrtoniReportConfig } from "ortoni-report";
|
||||
import * as path from 'path';
|
||||
|
||||
if (!process.env.CI) {
|
||||
// Environment variables are present in CI environment, no need to read from file
|
||||
|
|
@ -29,7 +30,7 @@ const reportConfig: OrtoniReportConfig = {
|
|||
open: "never",
|
||||
folderPath: "test-results",
|
||||
filename: "index.html",
|
||||
logo: "../data/logo.png",
|
||||
logo: "../business-logic/data/logo.png",
|
||||
title: "Test Report",
|
||||
showProject: false,
|
||||
projectName: "ISS-Nextgen-Playwright-Report",
|
||||
|
|
@ -38,6 +39,9 @@ const reportConfig: OrtoniReportConfig = {
|
|||
base64Image: true,
|
||||
};
|
||||
|
||||
export const reportFilePath = path.resolve(__dirname, './test-results/accessibility-report.html');
|
||||
export const jsonReportFilePath = path.resolve(__dirname, './test-results/accessibility-report.json');
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
/* Run tests in files in parallel */
|
||||
|
|
@ -51,9 +55,10 @@ export default defineConfig({
|
|||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: [
|
||||
['ortoni-report', reportConfig],
|
||||
['junit'],
|
||||
['list']
|
||||
],
|
||||
timeout: 120_000,
|
||||
timeout: 240_000,
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
|
|
@ -63,6 +68,7 @@ export default defineConfig({
|
|||
trace: 'on-first-retry',
|
||||
headless: process.env.CI ? true : false,
|
||||
screenshot: "only-on-failure",
|
||||
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ import essentialReplaceDynamicAdasTests from "./0005_EssentialReplaceDynamicAdas
|
|||
import essentialReplaceStaticAdasTests from "./0001_EssentialReplaceStatisAdas";
|
||||
import essentialVehicleLookupBailoutTests from "./0020_EssentialVehicleLookupBailout";
|
||||
import essentialPriceServiceErrorBailoutTests from "./0021_EssentialPriceServiceErrorBailout";
|
||||
import { forceAPIError, mockApiResponse } from "@impl/utils/HttpUtils";
|
||||
import { forceAPIError, mockApiManager } from "@impl/utils/HttpUtils";
|
||||
|
||||
import advancedScenario0002TestCases from "./advanced/0002a_ReplaceOemEndorsement";
|
||||
import ApiResponseInterceptUtil from "@impl/api/ApiResponseInterceptUtil";
|
||||
import advancedScenario0004aTestCases from "./advanced/0004a_NoDeductibleAdas";
|
||||
|
|
@ -46,6 +47,10 @@ import advancedScenario0020TestCases from "./advanced/0020a_NoCompChangeLoc";
|
|||
import advancedScenario0005TestCases from "./advanced/0005a_CapabilityQuestions";
|
||||
import advancedScenario0009TestCases from "./advanced/0009a_NoDeductibleFlorida";
|
||||
import advancedScenario0010TestCases from "./advanced/0010a_RearGlass";
|
||||
import advancedScenario0021TestCases from "./advanced/0021a_VehicleByPlate";
|
||||
import advancedScenario0022TestCases from "./advanced/0022a_VehicleByVIN";
|
||||
import { createAccessibilityHtmlReport } from "@impl/utils/ReportUtils";
|
||||
|
||||
|
||||
|
||||
test.describe.parallel('ISS QA Automation Regression', () => {
|
||||
|
|
@ -153,7 +158,7 @@ test.describe.parallel('ISS QA Automation Regression', () => {
|
|||
for (const testCase of essentialPriceServiceErrorBailoutTests) {
|
||||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
|
||||
|
||||
// Advanced Scenarios
|
||||
|
||||
// Scenario 0001a
|
||||
|
|
@ -165,7 +170,7 @@ test.describe.parallel('ISS QA Automation Regression', () => {
|
|||
for (const testCase of advancedScenario0002TestCases) {
|
||||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
|
||||
|
||||
// Scenario 0003a
|
||||
// Note: payment will fail in dev. Payment (PIA) works fine in SYS
|
||||
for (const testCase of advancedScenario0003TestCases) {
|
||||
|
|
@ -232,7 +237,7 @@ test.describe.parallel('ISS QA Automation Regression', () => {
|
|||
}
|
||||
|
||||
// Scenario 0016a
|
||||
// FIXME:
|
||||
// FIXME: Defect was created INSR-2138
|
||||
for (const testCase of advancedScenario0016TestCases) {
|
||||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
|
|
@ -252,10 +257,20 @@ test.describe.parallel('ISS QA Automation Regression', () => {
|
|||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
|
||||
// Scenario 0020a
|
||||
// Scenario 0020a : There's a defect open INSR-2149
|
||||
for (const testCase of advancedScenario0020TestCases) {
|
||||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
|
||||
// Scenario 0021a
|
||||
for (const testCase of advancedScenario0021TestCases) {
|
||||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
|
||||
// Scenario 0022a
|
||||
for (const testCase of advancedScenario0022TestCases) {
|
||||
test(...prepareTest(testCase, run, options, ruleEngine));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -263,9 +278,14 @@ test.afterEach(async ({ page, testInfo }) => {
|
|||
await TestCase.afterEachMethod(page, testInfo);
|
||||
});
|
||||
|
||||
async function run(page: Page, testInfo: TestInfo): Promise<void> {
|
||||
test.afterAll(() => {
|
||||
createAccessibilityHtmlReport();
|
||||
});
|
||||
|
||||
await testInfo.testCase.setup();
|
||||
async function run(page: Page, testInfo: TestInfo): Promise<void> {
|
||||
if (!(testInfo.testCase.testData?.isMockTesting ?? false)) {
|
||||
await testInfo.testCase.setup();
|
||||
}
|
||||
testInfo.testCase.setupPages(page);
|
||||
if (testInfo.testCase.testData.isAuthenticationRequired) {
|
||||
await testInfo.testCase.pages.welcomePage.gotoWithAuthentication(testInfo.testCase.testData!.clientTag!);
|
||||
|
|
@ -277,19 +297,25 @@ async function run(page: Page, testInfo: TestInfo): Promise<void> {
|
|||
}
|
||||
|
||||
async function runWorkflow(page: Page, testCase: TestCase) {
|
||||
// Intercept API Responses
|
||||
const apiResponseInterceptUtil = new ApiResponseInterceptUtil(testCase.testData);
|
||||
page.on('response', apiResponseInterceptUtil.handleInterceptResponse);
|
||||
if (testCase.testData?.isMockTesting ?? false) {
|
||||
// await mockApiManager.mockApiResponse(page, 'common', testCase.testData!.isMockTesting ?? false);
|
||||
await mockApiManager.mockApiResponse(page, testCase.name.split(':')[0], testCase.testData!.isMockTesting ?? false);
|
||||
|
||||
} else {
|
||||
// Intercept API Responses
|
||||
const apiResponseInterceptUtil = new ApiResponseInterceptUtil(testCase.testData);
|
||||
page.on('response', apiResponseInterceptUtil.handleInterceptResponse);
|
||||
await mockApiManager.mockApiResponse(page, 'common', true); // making sure no experiments
|
||||
}
|
||||
|
||||
// Destructure data for easy access
|
||||
const { customerDetails, claimDetails, vehicleDetails, vehicleDamage,
|
||||
appointmentDetails, isSafelite, endorsements,
|
||||
partQuestions, paymentDetails, isNoComp, isItac, isRecalNotification,
|
||||
partQuestions, paymentDetails, isNoComp, isItac, isRecalNotification,
|
||||
isRecalWarning, servicePackage, hasStateLawPopup, otherVehiclesOnPolicy,
|
||||
isSeparateApptsWarning, vehiclePartQuestions, editVehicleDetails,
|
||||
hasMilitaryWarning, capabilityQuestions } = testCase.testData;
|
||||
|
||||
hasMilitaryWarning, capabilityQuestions, isUseVehicleOnPolicy, isVehicleLookupValidations } = testCase.testData;
|
||||
|
||||
let { isPolicyFound } = testCase.testData; // Allow isPolicyFound to be re-assigned
|
||||
|
||||
// Destructure pages for easy access
|
||||
|
|
@ -304,8 +330,8 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
|
||||
// Destructure bailout flags
|
||||
const { isVehicleSelectBailout, isDoNotSeeMyShopBailout, isTpaNotEnabledBailout,
|
||||
isRequestCallbackBailout, isHeavyTruckVehicleBailout, isPartsServiceErrorBailout,
|
||||
isSafeliteNotTheProviderBailout, isVehicleLookupBailout, isPriceServiceErrorBailout } = testCase.testData.bailoutFlags || {};
|
||||
isHeavyTruckVehicleBailout, isPartsServiceErrorBailout,
|
||||
isVehicleLookupBailout, isPriceServiceErrorBailout } = testCase.testData.bailoutFlags || {};
|
||||
|
||||
const repairTypes: VehicleDamage[] = [
|
||||
VehicleDamage.WindshieldOneChip,
|
||||
|
|
@ -322,10 +348,6 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
|
||||
await test.step('WelcomePage >> Populate Customer Details', async () => {
|
||||
await welcomePage.populatePage(customerDetails!, claimDetails!, await welcomePage.hasCityInfo());
|
||||
|
||||
// mockApiResponse(page, 'location/api/v1/location/zip/43016', 'common', testCase.testData!.mockTesting || false);
|
||||
mockApiResponse(page, 'location/api/v1/location/zip/36116', 'common',testCase.testData!.isMockTesting || false);
|
||||
mockApiResponse(page, 'coverage/api/v1/coverage/policy-information', 'scenario1', testCase.testData!.isMockTesting || false);
|
||||
await welcomePage.nextPage();
|
||||
});
|
||||
|
||||
|
|
@ -341,16 +363,23 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
|
||||
if (isPolicyFound) {
|
||||
await test.step('PolicyVehiclesPage >> Select vehicle', async () => {
|
||||
await policyVehiclesPage.logReferralNumber();
|
||||
// Validate other vehicles on policy
|
||||
if (otherVehiclesOnPolicy && otherVehiclesOnPolicy.length > 0) {
|
||||
for (const vehicle of otherVehiclesOnPolicy) {
|
||||
await policyVehiclesPage.validateVehicleIsOnPolicy(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// Select vehicle
|
||||
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
if (!(isUseVehicleOnPolicy ?? true)) {
|
||||
await policyVehiclesPage.selectVehicleNotListed();
|
||||
await policyVehiclesPage.nextPage();
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
} else {
|
||||
// Select vehicle
|
||||
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
}
|
||||
});
|
||||
|
||||
if (isHeavyTruckVehicleBailout) {
|
||||
|
|
@ -369,12 +398,13 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
}
|
||||
|
||||
} else {
|
||||
await policyVehiclesPage.logReferralNumber();
|
||||
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||
await policyHolderDetailsPage.nextPage();
|
||||
});
|
||||
|
||||
if (isVehicleLookupBailout){
|
||||
if (isVehicleLookupBailout) {
|
||||
forceAPIError(page, '/vehicle/api/v1/vehicle/lookup')
|
||||
}
|
||||
|
||||
|
|
@ -437,11 +467,14 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isReplace && !(isPolicyFound)) {
|
||||
if (isReplace && (!(isPolicyFound) || !(isUseVehicleOnPolicy ?? true))) {
|
||||
|
||||
|
||||
await test.step('VehicleLookupPage >> Select Lookup Type' + vehicleDetails?.vehicleLookupType, async () => {
|
||||
await vehicleLookupPage.vehicleLookup(vehicleDetails!);
|
||||
});
|
||||
|
||||
|
||||
if (isVehicleSelectBailout) {
|
||||
await test.step('BailoutPage >> Validate Bailout', async () => {
|
||||
await vinLookupPage.enterVin(vehicleDetails!.vin!);
|
||||
|
|
@ -458,14 +491,22 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
});
|
||||
break;
|
||||
case VehicleLookupType.LicensePlateNumber:
|
||||
await test.step('VehicleLookupLicensePage >> Lookup by license plate: ' + vehicleDetails!.licensePlateNumber, async () => {
|
||||
await vehicleLookupLicensePage.enterPlateDetails(vehicleDetails!);
|
||||
await vehicleLookupLicensePage.nextPage();
|
||||
});
|
||||
if (isVehicleLookupValidations) {
|
||||
await test.step('VehicleLookupLicensePage >> Lookup by license plate: ' + vehicleDetails!.licensePlateNumber, async () => {
|
||||
await vehicleLookupLicensePage.enterPlateDetails(vehicleDetails!, isVehicleLookupValidations);
|
||||
await vehicleLookupLicensePage.nextPage();
|
||||
});
|
||||
|
||||
} else {
|
||||
await test.step('VehicleLookupLicensePage >> Lookup by license plate: ' + vehicleDetails!.licensePlateNumber, async () => {
|
||||
await vehicleLookupLicensePage.enterPlateDetails(vehicleDetails!);
|
||||
await vehicleLookupLicensePage.nextPage();
|
||||
});
|
||||
}
|
||||
break;
|
||||
case VehicleLookupType.Vin:
|
||||
await test.step('VinLookupPage >> Lookup by VIN: ' + vehicleDetails!.vin!, async () => {
|
||||
await vinLookupPage.enterVin(vehicleDetails!.vin!);
|
||||
await vinLookupPage.enterVin(vehicleDetails!.vin!, isVehicleLookupValidations);
|
||||
await vinLookupPage.nextPage();
|
||||
});
|
||||
break;
|
||||
|
|
@ -495,7 +536,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
if (isPolicyFound && (isItac || isNoComp)) {
|
||||
await coverageStatementPage.continueToScheduleButton.click();
|
||||
}
|
||||
|
||||
|
||||
await coverageStatementPage.nextPage();
|
||||
});
|
||||
|
||||
|
|
@ -511,7 +552,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
await providerPreferencePage.selectProvider(isSafelite);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// validations for Recal warning mesage
|
||||
if (isRecalWarning) {
|
||||
await serviceLocationPage.validateRecalWarning();
|
||||
|
|
@ -611,7 +652,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
await servicePackagesPage.nextPage();
|
||||
});
|
||||
|
||||
if (isPolicyFound && claimDetails!.policyDeductible > 0) {
|
||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true) && claimDetails!.policyDeductible > 0) {
|
||||
await test.step('PaymentMethodPage >> Execute Payment', async () => {
|
||||
await paymentMethodPage.executePayment(paymentDetails!);
|
||||
await paymentMethodPage.nextPage();
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const essentialReplaceDynamicAdasData: Partial<ITestData> = {
|
|||
damageCause: DamageType.Other
|
||||
},
|
||||
vehicleDetails: {
|
||||
year: '2021',
|
||||
year: '2020',
|
||||
make: 'BMW',
|
||||
model: '740',
|
||||
style: '4 door sedan',
|
||||
|
|
|
|||
|
|
@ -22,11 +22,19 @@ const customerDetails: ICustomerDetails = {
|
|||
country: 'United States'
|
||||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0002a${faker.string.uuid().substring(0,6)}`;
|
||||
var policyNumber = '';
|
||||
if ((process.env.ENABLE_MOCK_TESTING ?? 'false') === 'true') {
|
||||
policyNumber = '~AutomatedScenario0002aMockPolicy002';
|
||||
customerDetails.firstName = 'Rosie';
|
||||
customerDetails.lastName = 'Cormier';
|
||||
customerDetails.address.street = '69825 W Pine Street';
|
||||
} else {
|
||||
policyNumber = `~AutomatedScenario0002a${faker.string.uuid().substring(0, 6)}`;
|
||||
};
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0002a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0002Data: Partial<ITestData> = {
|
||||
isMockTesting: process.env.ENABLE_MOCK_TESTING === 'true' || false,
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
|
|
@ -41,6 +49,11 @@ const advancedScenario0002Data: Partial<ITestData> = {
|
|||
// optionToSelect: 'Green Tint, Blue Shade'
|
||||
// },
|
||||
// {
|
||||
// partQuestionType: PartQuestionType.WindshieldColor,
|
||||
// isOnPage: true,
|
||||
// optionToSelect: 'Green Tint'
|
||||
// },
|
||||
// {
|
||||
// partQuestionType: PartQuestionType.DriverFrontColor,
|
||||
// isOnPage: true,
|
||||
// optionToSelect: 'Green Tint'
|
||||
|
|
@ -75,7 +88,7 @@ const advancedScenario0002Data: Partial<ITestData> = {
|
|||
year: '2006',
|
||||
make: 'Chrysler',
|
||||
model: '300',
|
||||
style: ''
|
||||
style: '4 door sedan'
|
||||
},
|
||||
vehicleDamage: [
|
||||
// VehicleDamage.WindshieldThreeChips,
|
||||
|
|
@ -102,10 +115,10 @@ const advancedScenario0002Data: Partial<ITestData> = {
|
|||
const advancedClients = ClientData.getAdvancedClients();
|
||||
const advancedScenario0002TestCases: TestCase[] = [];
|
||||
for (const client of advancedClients) {
|
||||
const data = {...advancedScenario0002Data};
|
||||
const data = { ...advancedScenario0002Data };
|
||||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0002a Advanced Replace Deductible Client: "${client.accountName}"`,
|
||||
name: `0002a_Advanced_Replace_Deductible_Client: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||
testData: data
|
||||
}, undefined, '0002a');
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ const advancedScenario0016Data: Partial<ITestData> = {
|
|||
{
|
||||
partQuestionType: PartQuestionType.DriverVentColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Green Tint',
|
||||
secondaryQuestionOptionToSelect: 'solar, driver side, rear'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.PassengerFrontColor,
|
||||
|
|
@ -66,6 +67,11 @@ const advancedScenario0016Data: Partial<ITestData> = {
|
|||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.RearWindowColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
},
|
||||
],
|
||||
isSafelite: true,
|
||||
servicePackage: ServicePackage.Standard,
|
||||
|
|
@ -111,7 +117,7 @@ for (const client of advancedClients) {
|
|||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0016a Advanced Replace NoComp All Glass Client: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced', '@Flaky'],
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced', '@Defect-INSR-2138'],
|
||||
testData: data
|
||||
}, undefined, '0016a');
|
||||
advancedScenario0016TestCases.push(tc);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ for (const client of advancedClients) {
|
|||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0020a Advanced Repair Change Location Client: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced','@Defect-INSR-2149'],
|
||||
testData: data
|
||||
}, undefined, '0020a');
|
||||
advancedScenario0020TestCases.push(tc);
|
||||
|
|
|
|||
87
playwright-tests/tests/advanced/0021a_VehicleByPlate.ts
Normal file
87
playwright-tests/tests/advanced/0021a_VehicleByPlate.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import ClientData from "@business-logic/data/ClientData";
|
||||
import TestCase from "@business-logic/types/TestCase";
|
||||
import { DamageType, PartQuestionType, PaymentType, ServiceLocation, ServicePackage, VehicleDamage, VehicleLookupType } from "@business-logic/types/Enums";
|
||||
import { ITestData } from "@business-logic/types/ITestData"
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { getNextWeekday } from "@impl/utils/DateUtils";
|
||||
import MockPolicyData from "@business-logic/data/MockPolicyData";
|
||||
import { ICustomerDetails } from "@business-logic/types/CustomerDetails";
|
||||
|
||||
const nextWeekday = getNextWeekday();
|
||||
const customerDetails: ICustomerDetails = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: 'itqatest@safelite.com',
|
||||
phoneNumber: '614-531-0031',
|
||||
notes: 'Automated Test',
|
||||
address: {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'San Jose',
|
||||
state: 'CA',
|
||||
postalCode: '97230-6373',
|
||||
country: 'United States'
|
||||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0021a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0021a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0021Data: Partial<ITestData> = {
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
endorsements: undefined,
|
||||
isUseVehicleOnPolicy: false,
|
||||
isVehicleLookupValidations: true,
|
||||
vehiclePartQuestions: [
|
||||
|
||||
],
|
||||
isSafelite: true,
|
||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||
customerDetails: customerDetails,
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 500,
|
||||
damageDate: '2017-06-02',
|
||||
damageCause: DamageType.Vandalism
|
||||
},
|
||||
policySoap: policySoap,
|
||||
vehicleDetails: {
|
||||
year: '2003',
|
||||
make: 'Lexus',
|
||||
model: 'RX 300',
|
||||
style: undefined,
|
||||
vehicleLookupType: VehicleLookupType.LicensePlateNumber,
|
||||
licensePlateNumber: ['NoPlate753', 'BQ40903','1111'],
|
||||
licensePlateState: ['Illinois','Illinois','California'],
|
||||
},
|
||||
vehicleDamage: [
|
||||
VehicleDamage.WindshieldCrack,
|
||||
],
|
||||
appointmentDetails: {
|
||||
serviceLocation: ServiceLocation.InShop,
|
||||
shopAddress: undefined,
|
||||
appointmentDate: nextWeekday
|
||||
},
|
||||
paymentDetails: {
|
||||
paymentType: PaymentType.PayAtService
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add validation for deductible/covered amount
|
||||
const advancedClients = ClientData.getAdvancedClients();
|
||||
const advancedScenario0021TestCases: TestCase[] = [];
|
||||
for (const client of advancedClients) {
|
||||
const data = { ...advancedScenario0021Data };
|
||||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0021a Advanced client Vehicle By License Plate: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||
testData: data
|
||||
}, undefined, '0021a');
|
||||
advancedScenario0021TestCases.push(tc);
|
||||
}
|
||||
|
||||
export default advancedScenario0021TestCases;
|
||||
86
playwright-tests/tests/advanced/0022a_VehicleByVIN.ts
Normal file
86
playwright-tests/tests/advanced/0022a_VehicleByVIN.ts
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import ClientData from "@business-logic/data/ClientData";
|
||||
import TestCase from "@business-logic/types/TestCase";
|
||||
import { DamageType, PartQuestionType, PaymentType, ServiceLocation, ServicePackage, VehicleDamage, VehicleLookupType } from "@business-logic/types/Enums";
|
||||
import { ITestData } from "@business-logic/types/ITestData"
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { getNextWeekday } from "@impl/utils/DateUtils";
|
||||
import MockPolicyData from "@business-logic/data/MockPolicyData";
|
||||
import { ICustomerDetails } from "@business-logic/types/CustomerDetails";
|
||||
|
||||
const nextWeekday = getNextWeekday();
|
||||
const customerDetails: ICustomerDetails = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: 'itqatest@safelite.com',
|
||||
phoneNumber: '614-531-0031',
|
||||
notes: 'Automated Test',
|
||||
address: {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'San Jose',
|
||||
state: 'CA',
|
||||
postalCode: '97230-6373',
|
||||
country: 'United States'
|
||||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0021a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0021a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0021Data: Partial<ITestData> = {
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
endorsements: undefined,
|
||||
isUseVehicleOnPolicy: false,
|
||||
isVehicleLookupValidations: true,
|
||||
vehiclePartQuestions: [
|
||||
|
||||
],
|
||||
isSafelite: false,
|
||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||
customerDetails: customerDetails,
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 500,
|
||||
damageDate: '2017-06-02',
|
||||
damageCause: DamageType.Vandalism
|
||||
},
|
||||
policySoap: policySoap,
|
||||
vehicleDetails: {
|
||||
year: '2003',
|
||||
make: 'Lexus',
|
||||
model: 'RX 300',
|
||||
style: undefined,
|
||||
vehicleLookupType: VehicleLookupType.Vin,
|
||||
vin: ['1C4PJLCS6EW288461', '1HGCR2E30FA099831'],
|
||||
},
|
||||
vehicleDamage: [
|
||||
VehicleDamage.WindshieldCrack,
|
||||
],
|
||||
appointmentDetails: {
|
||||
serviceLocation: ServiceLocation.InShop,
|
||||
shopAddress: undefined,
|
||||
appointmentDate: nextWeekday
|
||||
},
|
||||
paymentDetails: {
|
||||
paymentType: PaymentType.PayAtService
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add validation for deductible/covered amount
|
||||
const advancedClients = ClientData.getAdvancedClients();
|
||||
const advancedScenario0022TestCases: TestCase[] = [];
|
||||
for (const client of advancedClients) {
|
||||
const data = { ...advancedScenario0021Data };
|
||||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0022a Advanced Client Vehicle By Vin: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||
testData: data
|
||||
}, undefined, '0022a');
|
||||
advancedScenario0022TestCases.push(tc);
|
||||
}
|
||||
|
||||
export default advancedScenario0022TestCases;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"userKey": 2004417,
|
||||
"sessionKey": 2419636,
|
||||
"sessionId": "8967dbc4-5081-47c4-a896-03050353d9e2",
|
||||
"userId": "2ea43842-440b-4362-a72f-105d987f4bc1",
|
||||
"deviceId": "2ea43842-440b-4362-a72f-105d987f4bc1",
|
||||
"version": 1,
|
||||
"status": 1,
|
||||
"error": null
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"accountNumber": "550036",
|
||||
"detailedErrorMessage": null,
|
||||
"notes": null,
|
||||
"hasPolicies": false,
|
||||
"deductible": 50,
|
||||
"status": null,
|
||||
"noCoverage": false,
|
||||
"isOEMEndorsed": false,
|
||||
"policyData": "AMjHAgrjFS8H8IiDcI9sC8DUxbkV/fm1HmxAnMOiIunuYyVWRdFu7IcgtzX6CCuZINR8ZapGM0Jume0ZhoISUQ/DHvocaVjtdjZEPbGktguUIQgCrthBdHKYxQyrleKaDlXp5Sit3Vgfkj+eKUJvhegia01DFcUqUOEp9nlLMf7RMbjUkHAGogx5CkK9hfGO7iRQ/SJ9YQ2BoLPZgAds9x+LasOS7Wy1+BVyFUswlvgestN6STUF7EzZ8uS+Rb6atNHYqM2ir3tEwxMDp2uSma2CSiS755MLIYKqZlB/UoXKgsc7U1hxIrP+c8LxXOk2",
|
||||
"referralCorrelationId": "097de2c2-ab3c-455e-8e31-fb2951c68d0a",
|
||||
"referralNumber": null,
|
||||
"isSuccess": true,
|
||||
"isError": false,
|
||||
"errorCode": null,
|
||||
"errorMessage": null,
|
||||
"successMessage": null
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"referralNumber": "108979",
|
||||
"referralSequenceNumber": "10084346",
|
||||
"referralDate": "2025-02-08T16:07:59.93",
|
||||
"referralCorrelationId": "af625adc-87e5-47fc-8de6-0a003fe7003b",
|
||||
"parentAccountNumber": 550036,
|
||||
"billToAccountNumber": "214616",
|
||||
"crmCustomerId": 855298,
|
||||
"savedSessionId": "8f0bd26a-ef61-4929-a013-6f376a881052",
|
||||
"eon": "S10080197",
|
||||
"workOrderNumber": "",
|
||||
"workOrderId": "",
|
||||
"workOrderStatus": "",
|
||||
"customerPortalLoginToken": "00000000-0000-0000-0000-000000000000",
|
||||
"lockToken": null,
|
||||
"settledTenderAmount": 0.0,
|
||||
"isRecalAckOptIn": false
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"policies": [
|
||||
{
|
||||
"policyEffectiveDate": "0001-01-01T00:00:00",
|
||||
"expirationDate": "0001-01-01T00:00:00",
|
||||
"type": null,
|
||||
"lineOfBusiness": null,
|
||||
"policyNumber": "~AutomatedScenario0002a126b81",
|
||||
"status": null,
|
||||
"source": null,
|
||||
"insureds": [
|
||||
{
|
||||
"firstName": "Rosie",
|
||||
"lastName": "Cormier",
|
||||
"businessName": null,
|
||||
"address": "69825 W Pine Street",
|
||||
"city": "PLANO",
|
||||
"state": "TX",
|
||||
"zipCode": "75023",
|
||||
"phones": null,
|
||||
"email": null,
|
||||
"driverLicenseState": null,
|
||||
"relationToInsured": null,
|
||||
"companyCode": "LIBERTY",
|
||||
"customerId": null
|
||||
},
|
||||
{
|
||||
"firstName": "Rosie",
|
||||
"lastName": "Cormier",
|
||||
"businessName": null,
|
||||
"address": "69825 W Pine Street",
|
||||
"city": "PLANO",
|
||||
"state": "TX",
|
||||
"zipCode": "75023",
|
||||
"phones": null,
|
||||
"email": null,
|
||||
"driverLicenseState": null,
|
||||
"relationToInsured": null,
|
||||
"companyCode": "LIBERTY",
|
||||
"customerId": null
|
||||
}
|
||||
],
|
||||
"vehicles": [
|
||||
{
|
||||
"id": 0,
|
||||
"vehicleYear": "2006",
|
||||
"vehicleMake": "CHRY",
|
||||
"vehicleModel": "300",
|
||||
"vehicleStyle": null,
|
||||
"licensePlate": "UNKNOWN",
|
||||
"vin": "2C3KA53G06H407823",
|
||||
"driver": null,
|
||||
"owner": null,
|
||||
"coverages": [
|
||||
{
|
||||
"code": "COMP",
|
||||
"deductible": 50,
|
||||
"individualLimit": 0,
|
||||
"occurrenceLimit": 0,
|
||||
"dayLimit": 0
|
||||
}
|
||||
],
|
||||
"fleetNumber": null,
|
||||
"fleetUnitNumber": "1",
|
||||
"endorsements": [
|
||||
"OEM Approved"
|
||||
]
|
||||
}
|
||||
],
|
||||
"taxExempt": "FALSE",
|
||||
"policyData": "AMjHAgrjFS8H8IiDcI9sC8DUxbkV/fm1HmxAnMOiIunuYyVWRdFu7IcgtzX6CCuZINR8ZapGM0Jume0ZhoISUQ/DHvocaVjtdjZEPbGktguUIQgCrthBdHKYxQyrleKaDlXp5Sit3Vgfkj+eKUJvhegia01DFcUqUOEp9nlLMf7RMbjUkHAGogx5CkK9hfGO7zKZfyYsWKqUbh5UgaO/fzdKBhMHFKIWMsG5YydLN/4G9x3UDfZ//kNQ+vG3eN1RQ5kv9sMQXS0pOyG9Mqy0XvKf6SozAlPpBeX53PrrPrPeFpVRGalafXgrDDx9D2OaP72dhCnwEuRRQzQ7Gj4RsrtrVOvQjgHHMSlg8X7U6TW7Mni/Q61XrCkj3/rHySrL"
|
||||
}
|
||||
],
|
||||
"referralCorrelationId": "097de2c2-ab3c-455e-8e31-fb2951c68d0a",
|
||||
"referralNumber": null,
|
||||
"accountNumber": "550036",
|
||||
"isSuccess": true,
|
||||
"isError": false,
|
||||
"errorCode": null,
|
||||
"errorMessage": null,
|
||||
"successMessage": null
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"claimantId": null,
|
||||
"claimNumber": "0589139920001",
|
||||
"notes": null,
|
||||
"dispatchNumber": null,
|
||||
"deductible": 0,
|
||||
"referralCorrelationId": "097de2c2-ab3c-455e-8e31-fb2951c68d0a",
|
||||
"referralNumber": null,
|
||||
"accountNumber": "550036",
|
||||
"isSuccess": true,
|
||||
"isError": false,
|
||||
"errorCode": null,
|
||||
"errorMessage": null,
|
||||
"successMessage": "registered"
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"experiments": [
|
||||
{
|
||||
"universeName": "PIAInsurance",
|
||||
"universeId": 640,
|
||||
"testName": "PIAInsurance_V1",
|
||||
"testId": 504,
|
||||
"variationName": "YesShowPIAInsurance_TEST",
|
||||
"variationId": 1430,
|
||||
"isActive": true,
|
||||
"isExposed": true,
|
||||
"userPartitionNumber": 85,
|
||||
"assignmentId": 14838407,
|
||||
"settings": {
|
||||
"DisplayPIAInsurance": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
[]
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
{
|
||||
"mobileProviderNumber": "001813",
|
||||
"shopProviders": [
|
||||
{
|
||||
"address": {
|
||||
"city": "PLANO",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "1601 E PLANO PKWY",
|
||||
"streetAddress2": "STE 150",
|
||||
"zipCode": "75074",
|
||||
"zipCodeCtu": "01813"
|
||||
},
|
||||
"distanceInMiles": 4.187648412874978,
|
||||
"providerNumber": "001813",
|
||||
"companyName": "SAFELITE AUTOGLASS - DALLAS-FT.WO,TX SOR-CTU",
|
||||
"phoneNumber": "9724237183",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "MCKINNEY",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "417 POWER HOUSE ST.",
|
||||
"streetAddress2": "STE A",
|
||||
"zipCode": "75071",
|
||||
"zipCodeCtu": "01813"
|
||||
},
|
||||
"distanceInMiles": 13.220085913669747,
|
||||
"providerNumber": "005318",
|
||||
"companyName": "SAFELITE AUTOGLASS - MCKINNEY, TX",
|
||||
"phoneNumber": "9725624492",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "LEWISVILLE",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "2129 S STEMMONS FWY",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "75067",
|
||||
"zipCodeCtu": "01813"
|
||||
},
|
||||
"distanceInMiles": 14.553951205638858,
|
||||
"providerNumber": "004542",
|
||||
"companyName": "SAFELITE AUTOGLASS - LEWISVILLE, TX",
|
||||
"phoneNumber": "4694442057",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "MESQUITE",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "2131 N TOWN EAST BLVD",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "75150",
|
||||
"zipCodeCtu": "01813"
|
||||
},
|
||||
"distanceInMiles": 17.86005691117364,
|
||||
"providerNumber": "004541",
|
||||
"companyName": "SAFELITE AUTOGLASS - MESQUITE, TX",
|
||||
"phoneNumber": "9722889891",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "N RICHLAND HILLS",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "5649 RUFE SNOW DR",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "76180",
|
||||
"zipCodeCtu": "04544"
|
||||
},
|
||||
"distanceInMiles": 32.558897054726366,
|
||||
"providerNumber": "006504",
|
||||
"companyName": "SAFELITE AUTOGLASS - FORT WORTH, TX RDU",
|
||||
"phoneNumber": "8176569791",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "ARLINGTON",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "2411 S COOPER ST",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "76015",
|
||||
"zipCodeCtu": "04544"
|
||||
},
|
||||
"distanceInMiles": 33.065576901075474,
|
||||
"providerNumber": "004540",
|
||||
"companyName": "SAFELITE AUTOGLASS - ARLINGTON, TX",
|
||||
"phoneNumber": "8175224300",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "GREENVILLE",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "7907 TRADERS CIR",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "75402",
|
||||
"zipCodeCtu": "01813"
|
||||
},
|
||||
"distanceInMiles": 36.369381330667089,
|
||||
"providerNumber": "005317",
|
||||
"companyName": "SAFELITE AUTOGLASS - GREENVILLE, TX",
|
||||
"phoneNumber": "9034501771",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "FORT WORTH",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "2751 NORTHERN CROSS BLVD",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "76137",
|
||||
"zipCodeCtu": "04544"
|
||||
},
|
||||
"distanceInMiles": 36.676844951002508,
|
||||
"providerNumber": "004544",
|
||||
"companyName": "SAFELITE AUTOGLASS - FORT WORTH, TX",
|
||||
"phoneNumber": "2143283111",
|
||||
"isSafeliteShop": true
|
||||
},
|
||||
{
|
||||
"address": {
|
||||
"city": "TYLER",
|
||||
"country": "US",
|
||||
"state": "TX",
|
||||
"streetAddress": "4043 S BROADWAY AVE",
|
||||
"streetAddress2": "",
|
||||
"zipCode": "75701",
|
||||
"zipCodeCtu": "01813"
|
||||
},
|
||||
"distanceInMiles": 98.1186957553462,
|
||||
"providerNumber": "000714",
|
||||
"companyName": "SAFELITE AUTOGLASS - TYLER, TX",
|
||||
"phoneNumber": "9035972059",
|
||||
"isSafeliteShop": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"containsMilitaryBase": false,
|
||||
"isServiceable": true,
|
||||
"isValid": true,
|
||||
"state": "TX",
|
||||
"providerNumber": "01813",
|
||||
"zipCodeCtu": "01813"
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"windshieldOptions": {
|
||||
"availableReplacementOptions": [
|
||||
"Single"
|
||||
],
|
||||
"isRepairAvailable": true
|
||||
},
|
||||
"backGlassOptions": {
|
||||
"availableReplacementOptions": [
|
||||
"Stationary"
|
||||
]
|
||||
},
|
||||
"driverSideOptions": {
|
||||
"availableReplacementOptions": [
|
||||
"Back",
|
||||
"Front"
|
||||
]
|
||||
},
|
||||
"passengerSideOptions": {
|
||||
"availableReplacementOptions": [
|
||||
"Back",
|
||||
"Front"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"partsOrQuestions": [
|
||||
{
|
||||
"glassPiece": {
|
||||
"name": "Single",
|
||||
"location": "Windshield"
|
||||
},
|
||||
"parts": [
|
||||
{
|
||||
"childPartQuestions": [],
|
||||
"basePartNumber": "DW01571",
|
||||
"safelitePartNumber": "DW01571 GTNOEM",
|
||||
"color": "Green Tint",
|
||||
"requiresRecalibration": false,
|
||||
"recalibrationType": null,
|
||||
"canSafeliteRecalibrate": false,
|
||||
"requiresCapabilityQuestions": false,
|
||||
"childParts": [
|
||||
{
|
||||
"partNumber": "GGG 1571",
|
||||
"safelitePartNumber": "GGG 1571"
|
||||
}
|
||||
],
|
||||
"partNumber": "DW01571GTNNOEM",
|
||||
"description": "",
|
||||
"partType": "WINDSHIELD"
|
||||
}
|
||||
],
|
||||
"partQuestions": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"partsOrQuestions": [
|
||||
{
|
||||
"glassPiece": {
|
||||
"name": "Single",
|
||||
"location": "Windshield"
|
||||
},
|
||||
"parts": [
|
||||
{
|
||||
"childPartQuestions": [],
|
||||
"basePartNumber": "DW01571",
|
||||
"safelitePartNumber": "DW01571 GTNOEM",
|
||||
"color": "Green Tint",
|
||||
"requiresRecalibration": false,
|
||||
"recalibrationType": null,
|
||||
"canSafeliteRecalibrate": false,
|
||||
"requiresCapabilityQuestions": false,
|
||||
"childParts": [
|
||||
{
|
||||
"partNumber": "GGG 1571",
|
||||
"safelitePartNumber": "GGG 1571"
|
||||
}
|
||||
],
|
||||
"partNumber": "DW01571GTNNOEM",
|
||||
"description": "",
|
||||
"partType": "WINDSHIELD"
|
||||
}
|
||||
],
|
||||
"partQuestions": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"partNumber":"RAIN REPEL","description":null,"partType":"RAIN DEFENSE"}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[
|
||||
{
|
||||
"partNumber": "SBB22",
|
||||
"description": "SAFELITE BEAM BLADE 22",
|
||||
"partType": "FRONT WIPER"
|
||||
},
|
||||
{
|
||||
"partNumber": "SBB22",
|
||||
"description": "SAFELITE BEAM BLADE 22",
|
||||
"partType": "FRONT WIPER"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"lineItems": [
|
||||
{
|
||||
"partNumber": "RAIN REPEL",
|
||||
"promoCode": null,
|
||||
"laborAmount": 0.0,
|
||||
"sellingPrice": 44.99,
|
||||
"kitPrice": 0,
|
||||
"salesTax": null
|
||||
},
|
||||
{
|
||||
"partNumber": "SBB22",
|
||||
"promoCode": null,
|
||||
"laborAmount": 0.0,
|
||||
"sellingPrice": 34.99,
|
||||
"kitPrice": 0,
|
||||
"salesTax": null
|
||||
},
|
||||
{
|
||||
"partNumber": "SBB22",
|
||||
"promoCode": null,
|
||||
"laborAmount": 0.0,
|
||||
"sellingPrice": 34.99,
|
||||
"kitPrice": 0,
|
||||
"salesTax": null
|
||||
}
|
||||
],
|
||||
"serverData": "KcYkmhhx3j2jfrKcPIai5c3vxIPezYw3algekZCIJ1nRzZHsoYWmD//QlA9cNAqo7E4vA4lcilhi/EbXZ5BfIvc9C7c7sl9TGGbrA2A3QUiVi9Q+eQQWUrGSlb5Te3PyfK8g5A+gvcXvn+YSjH0tiZuykzLPDmbZaUNkY09OTOynQ4jR2G6ZjxdvkFOecp6vocPznIZHxkT4ag0MWr73pMB3WTWP+yY6Ej6yheEvcCBO+TPGJ4FKsJ5tXm5Y4+pqAA0MbC5nB2qLFSeDuPA4aPe5x//6zjOavPfOpT1+RwOZWlPx5vwfv0dncNgn/itTlZwHj4B4YwZqc/y7JJJLh7nlT8IPB5tg5ISpK8tOyCHKmbUT3ABAL236U98EiydC45k9uSxRDklR+BVvq0aV7EieYbewrrvrbKK1Wsk0rcwBCrRimLJfecvP37qqm/vLzyRYppxSXXPkdn2i/Er81LQbaNKLAReRN9oncgO1k4Q="
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"isItac": false,
|
||||
"isItacOptimized": null,
|
||||
"primaryBillToNumber": null,
|
||||
"partsWerePriced": true,
|
||||
"lineItems": [],
|
||||
"serverData": "KcYkmhhx3j2jfrKcPIai5c3vxIPezYw3algekZCIJ1nRzZHsoYWmD//QlA9cNAqo7E4vA4lcilhi/EbXZ5BfIlUjQng0T1GMzltEwIcGbNw="
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"taxedLineItems": [
|
||||
{
|
||||
"partNumber": "SBB22",
|
||||
"promoCode": null,
|
||||
"laborAmount": 0,
|
||||
"sellingPrice": 34.99,
|
||||
"kitPrice": 0,
|
||||
"salesTax": 2.89
|
||||
},
|
||||
{
|
||||
"partNumber": "SBB22",
|
||||
"promoCode": null,
|
||||
"laborAmount": 0,
|
||||
"sellingPrice": 34.99,
|
||||
"kitPrice": 0,
|
||||
"salesTax": 2.89
|
||||
},
|
||||
{
|
||||
"partNumber": "RAIN REPEL",
|
||||
"promoCode": null,
|
||||
"laborAmount": 0,
|
||||
"sellingPrice": 44.99,
|
||||
"kitPrice": 0,
|
||||
"salesTax": 3.71
|
||||
}
|
||||
],
|
||||
"serverData": "KcYkmhhx3j2jfrKcPIai5c3vxIPezYw3algekZCIJ1nRzZHsoYWmD//QlA9cNAqo7E4vA4lcilhi/EbXZ5BfIvc9C7c7sl9TGGbrA2A3QUiVi9Q+eQQWUrGSlb5Te3PyfK8g5A+gvcXvn+YSjH0tie6XYRgOnhi6ArHjHJ3GTgCmWIhMUosEpnBrUg3/W5ci/3UF4sCnDpihiJPPiMCnOMjzvWp1/xTg5jaoE8N8otARbxQ73ObbvZCJndil/EaSbqYMvL+ymPvDJHPoAfbXUJc90Drlef4gvSV1d6HEZGR/zwoKYipecNPSXcXzRGKrfxgmViszg1d1PyncoyVQrokAIl1KPRmDPJso5CmGrdDjEYsTV0SXUd0NcphMKd8wVrx7QUCLiyW8Vee7cVjWFnqdhkeJ9PYb14WoNb4j1cLJv39ofMcTmaJMI/maAcA8XKPOuhdWTTqWBXOPq3ax1g=="
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
"estimatedServiceMinutesMinimum": 60,
|
||||
"estimatedServiceMinutesMaximum": 120,
|
||||
"days": [
|
||||
{
|
||||
"date": "2025-02-22",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20873*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"date": "2025-02-24",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20875*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"date": "2025-02-25",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20876*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"date": "2025-02-26",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20877*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"date": "2025-02-27",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20878*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"date": "2025-02-28",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20879*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"date": "2025-03-01",
|
||||
"timeSlots": [
|
||||
{
|
||||
"id": "01813-01813-S-B*20880*ALL DAY DROP OFF",
|
||||
"startTime": "07:30",
|
||||
"endTime": "17:00",
|
||||
"offerPremium": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"provisionalTriggers": []
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"carId": "CR00056707",
|
||||
"category": "CAR",
|
||||
"year": 2006,
|
||||
"make": "Chrysler",
|
||||
"model": "300",
|
||||
"style": "4 door sedan",
|
||||
"imageUrl": "https://dbhdyzvm8lm25.cloudfront.net/color_0320_001/MY2006/3118/3118_cc0320_001_PWG.jpg",
|
||||
"imageVifNumber": "3118",
|
||||
"imageVifColor": "white",
|
||||
"canSafeliteService": true,
|
||||
"recalibrationServices": [],
|
||||
"isMobileStaticRecalibrationApplicable": false
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"experiments": [
|
||||
{
|
||||
"universeName": "PIAInsurance",
|
||||
"universeId": 640,
|
||||
"testName": "PIAInsurance_V1",
|
||||
"testId": 504,
|
||||
"variationName": "YesShowPIAInsurance_TEST",
|
||||
"variationId": 1430,
|
||||
"isActive": true,
|
||||
"isExposed": true,
|
||||
"userPartitionNumber": 12,
|
||||
"assignmentId": 14863748,
|
||||
"settings": {
|
||||
"DisplayPIAInsurance": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"containsMilitaryBase": false,
|
||||
"isServiceable": true,
|
||||
"isValid": false,
|
||||
"state": "AL",
|
||||
"providerNumber": "00795",
|
||||
"zipCodeCtu": "01872"
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"containsMilitaryBase": false,
|
||||
"isServiceable": true,
|
||||
"isValid": false,
|
||||
"state": "OH",
|
||||
"providerNumber": "03357",
|
||||
"zipCodeCtu": "01820"
|
||||
}
|
||||
|
|
@ -1,12 +1,25 @@
|
|||
{
|
||||
"common": {
|
||||
"location/api/v1/location/zip/36116": "common/location/api/v1/location/zip/36116.json",
|
||||
"location/api/v1/location/zip/43016": "common/location/api/v1/location/zip/43016.json"
|
||||
"experiments/api/v1/experiments/run": "common/experiments/api/v1/experiments/run.json"
|
||||
},
|
||||
"scenario1": {
|
||||
"coverage/api/v1/coverage/policy-information": "scenario1/coverage/api/v1/coverage/policy-information.json"
|
||||
},
|
||||
"scenario2": {
|
||||
"location/api/v1/location/zip/36116": "scenario2/coverage/api/v1/coverage/policy-information.json"
|
||||
"0002a_Advanced_Replace_Deductible_Client": {
|
||||
"location/api/v1/location/zip/75023": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/zip/75023.json",
|
||||
"coverage/api/v1/coverage/policy-information": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/policy-information.json",
|
||||
"coverage/api/v1/coverage/order/api/v1/order/save-session/iss": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/order/api/v1/order/save-session/iss.json",
|
||||
"experiments/api/v1/experiments/run": "0002a_Advanced_Replace_Deductible_Client/experiments/api/v1/experiments/run.json",
|
||||
"vehicle/api/v1/vehicle/lookup": "0002a_Advanced_Replace_Deductible_Client/vehicle/api/v1/vehicle/lookup.json",
|
||||
"parts/api/v1/parts/damage-options/CR00056707": "0002a_Advanced_Replace_Deductible_Client/parts/api/v1/parts/damage-options/CR00056707.json",
|
||||
"parts/api/v1/parts/parts-or-questions": "0002a_Advanced_Replace_Deductible_Client/parts/api/v1/parts/parts-or-questions.json",
|
||||
"coverage/api/v1/coverage/final-deductible": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/final-deductible.json",
|
||||
"coverage/api/v1/coverage/register-claim": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/register-claim.json",
|
||||
"price/api/v1/price/order-items-with-itac-pricing": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/order-items-with-itac-pricing.json",
|
||||
"location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM.json",
|
||||
"schedule/api/v1/schedule/shop-time-slots": "0002a_Advanced_Replace_Deductible_Client/schedule/api/v1/schedule/shop-time-slots.json",
|
||||
"location/api/v1/location/alert-reasons/01813": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/alert-reasons/01813.json",
|
||||
"parts/api/v1/parts/rain-defense": "0002a_Advanced_Replace_Deductible_Client/parts/api/v1/parts/rain-defense.json",
|
||||
"price/api/v1/price/combined-quote": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/combined-quote.json"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue