Add guidelines for creating and maintaining tests in .aiassistant/rules/Creating and maintaining tests.md
- Introduced detailed instructions for test development using WebdriverIO, covering structure, naming conventions, and best practices. - Added examples for browser interactions, assertions, and handling internationalization (i18n) in tests. - Documented prerequisites for mobile testing and best practices for maintaining test cases. Enhance SelfServeTasks capabilities by introducing `services` management - Added `services` property to `SelfServeTasks` for task-specific service handling. - Implemented logic to determine and update allowed services dynamically based on active tasks. - Extended machine availability check (`isMachineAvailable`) to consider services allowed per task. Expand backend support for lane services - Added new endpoints to manage lane services (`/modules/self-serve/lane/services/allowed` and `/modules/self-serve/lane/relay/machine/enable`). - Extended OpenAPI specifications to include service configuration for tasks and validation of lane services. Modify SelfServe UI components for displaying allowed services - Updated multiple screens to show allowed services based on active tasks. - Added tags for visualizing allowed task services in `SelfServeTryModal` and `SelfServeTasksTable`. Add `i18n-settings-wheel.spec.js` for translation key verification - Added new test suite to ensure i18n translation parity between English and Danish locale files for `settings_wheel`. - Implemented checks to validate key presence and exact match across both languages.
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Test to verify i18n translations for ActionSettingsWheelButton component
|
||||
* are properly defined in both English and Danish locale files.
|
||||
*/
|
||||
|
||||
describe('i18n Settings Wheel Translations', () => {
|
||||
const settingsWheelKeys = [
|
||||
'close',
|
||||
'change_password',
|
||||
'enter_password',
|
||||
'please_enter_password',
|
||||
'password_changed',
|
||||
'password_changed_text',
|
||||
'error',
|
||||
'error_changing_password',
|
||||
'scan_qr_to_login',
|
||||
'copy_link',
|
||||
'link_copied',
|
||||
'booking',
|
||||
'mark_as_completed',
|
||||
'view_booking_new_tab',
|
||||
'change_association',
|
||||
'associate_order',
|
||||
'change_order',
|
||||
'delete_booking',
|
||||
'view_lane_new_tab',
|
||||
'view_order_new_tab',
|
||||
'attach_wash_certificate',
|
||||
'change_customer',
|
||||
'change_invoice_collection',
|
||||
'download_invoice',
|
||||
'delete_order',
|
||||
'view_invoice_collection_new_tab',
|
||||
'view_vehicle_new_tab',
|
||||
'view_customer_new_tab',
|
||||
'login_as_customer',
|
||||
'login_as_user',
|
||||
'login_as_user_qr',
|
||||
'show_qr_code',
|
||||
'show_customer',
|
||||
'edit_permissions',
|
||||
'delete_user',
|
||||
'attached_files',
|
||||
'open_attached_file',
|
||||
'error_downloading_attachment',
|
||||
'no_actions_defined',
|
||||
'view_lane_setup_new_tab'
|
||||
];
|
||||
|
||||
it('should have all settings_wheel translations defined in English', async () => {
|
||||
await browser.url('/');
|
||||
|
||||
const result = await browser.executeAsync(async (keys, done) => {
|
||||
try {
|
||||
const response = await fetch('/src/i18n/locales/en.json');
|
||||
const data = await response.json();
|
||||
|
||||
// Get the top-level keys to understand structure
|
||||
const topKeys = Object.keys(data);
|
||||
|
||||
// Check if admin exists
|
||||
if (!data.admin) {
|
||||
done({ success: false, error: 'admin namespace not found. Top keys: ' + topKeys.slice(0, 10).join(', ') });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.admin.pos) {
|
||||
done({ success: false, error: 'admin.pos not found. Admin keys: ' + Object.keys(data.admin).slice(0, 10).join(', ') });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.admin.pos.settings_wheel) {
|
||||
done({ success: false, error: 'admin.pos.settings_wheel not found. Pos keys: ' + Object.keys(data.admin.pos).slice(0, 15).join(', ') });
|
||||
return;
|
||||
}
|
||||
|
||||
const missingKeys = [];
|
||||
for (const key of keys) {
|
||||
if (!data.admin.pos.settings_wheel[key]) {
|
||||
missingKeys.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingKeys.length > 0) {
|
||||
done({ success: false, error: 'Missing keys: ' + missingKeys.join(', ') });
|
||||
} else {
|
||||
done({ success: true, keyCount: Object.keys(data.admin.pos.settings_wheel).length });
|
||||
}
|
||||
} catch (e) {
|
||||
done({ success: false, error: 'Exception: ' + e.message });
|
||||
}
|
||||
}, settingsWheelKeys);
|
||||
|
||||
console.log('English result:', JSON.stringify(result));
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('should have all settings_wheel translations defined in Danish', async () => {
|
||||
await browser.url('/');
|
||||
|
||||
const result = await browser.executeAsync(async (keys, done) => {
|
||||
try {
|
||||
const response = await fetch('/src/i18n/locales/da.json');
|
||||
const data = await response.json();
|
||||
|
||||
// Get the top-level keys to understand structure
|
||||
const topKeys = Object.keys(data);
|
||||
|
||||
// Check if admin exists
|
||||
if (!data.admin) {
|
||||
done({ success: false, error: 'admin namespace not found. Top keys: ' + topKeys.slice(0, 10).join(', ') });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.admin.pos) {
|
||||
done({ success: false, error: 'admin.pos not found. Admin keys: ' + Object.keys(data.admin).slice(0, 10).join(', ') });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.admin.pos.settings_wheel) {
|
||||
done({ success: false, error: 'admin.pos.settings_wheel not found. Pos keys: ' + Object.keys(data.admin.pos).slice(0, 15).join(', ') });
|
||||
return;
|
||||
}
|
||||
|
||||
const missingKeys = [];
|
||||
for (const key of keys) {
|
||||
if (!data.admin.pos.settings_wheel[key]) {
|
||||
missingKeys.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingKeys.length > 0) {
|
||||
done({ success: false, error: 'Missing keys: ' + missingKeys.join(', ') });
|
||||
} else {
|
||||
done({ success: true, keyCount: Object.keys(data.admin.pos.settings_wheel).length });
|
||||
}
|
||||
} catch (e) {
|
||||
done({ success: false, error: 'Exception: ' + e.message });
|
||||
}
|
||||
}, settingsWheelKeys);
|
||||
|
||||
console.log('Danish result:', JSON.stringify(result));
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('should have the same keys in both locales', async () => {
|
||||
await browser.url('/');
|
||||
|
||||
const result = await browser.executeAsync(async (done) => {
|
||||
try {
|
||||
const enResponse = await fetch('/src/i18n/locales/en.json');
|
||||
const en = await enResponse.json();
|
||||
|
||||
const daResponse = await fetch('/src/i18n/locales/da.json');
|
||||
const da = await daResponse.json();
|
||||
|
||||
if (!en.admin?.pos?.settings_wheel || !da.admin?.pos?.settings_wheel) {
|
||||
done({ success: false, error: 'settings_wheel not found in one or both locales' });
|
||||
return;
|
||||
}
|
||||
|
||||
const enKeys = Object.keys(en.admin.pos.settings_wheel).sort();
|
||||
const daKeys = Object.keys(da.admin.pos.settings_wheel).sort();
|
||||
|
||||
const match = JSON.stringify(enKeys) === JSON.stringify(daKeys);
|
||||
done({ success: match, enCount: enKeys.length, daCount: daKeys.length });
|
||||
} catch (e) {
|
||||
done({ success: false, error: 'Exception: ' + e.message });
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Parity result:', JSON.stringify(result));
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user