Integration with Web Components
External libraries work alongside components created in the ReAPI web editor.
Loading Order
Scripts load in this sequence:
1. Built-in Libraries
└── Lodash, Faker, Zod, Ky, Luxon (always available)
2. External Libraries (your code)
└── Loaded by URL, in registration order
3. Global Scripts (web editor)
└── Can call external library functions
4. Inline Code (node-level)
└── Can call everything aboveKey insight: External libraries load first, so web-created scripts can use your functions.
Calling External Functions from Web Editor
Once your library is synced, use it in global scripts:
// Global script in web editor
class $$PaymentUtils {
static validateCard(cardNumber) {
// Use external library function
return MyTestLib.validators.isValidCreditCard(cardNumber);
}
static generateTestPayment() {
// Use external library generator
return MyTestLib.generatePaymentData({
amount: _.random(100, 1000),
currency: "USD",
});
}
}Calling Web Functions from External Library
Your external library can call global scripts that loaded before inline code:
// In external library
function: async () => {
// ✅ Can use built-in libraries
const id = faker.string.uuid();
// ✅ Can use other external library functions
const hash = MyTestLib.utils.sha256(data);
// ❌ Cannot directly call web-created global scripts
// (they load after external libraries)
// $$WebUtils.doSomething(); // Won't work
}Workaround: Pass web-created utilities via context:
// In web global script (loads after external lib)
$context.webUtils = {
formatCurrency: (amount) => $$Formatters.currency(amount),
validateOrder: (order) => $$Validators.order(order),
};// In external test case
function: async () => {
// Access via context
const formatted = $context.webUtils?.formatCurrency(100);
}Namespace Conventions
Avoid conflicts with consistent naming:
| Source | Convention | Example |
|---|---|---|
| External Library | LibName.function | MyTestLib.validate() |
| Web Global Script | $$ClassName.method | $$Utils.format() |
| Built-in | Global name | faker.internet.email() |
// Clear, no conflicts
const hash = MyTestLib.hashGenerator.sha256(data); // External
const formatted = $$Formatters.currency(amount); // Web
const email = faker.internet.email(); // Built-inSharing Schemas
Define schemas in external library, use everywhere:
// src/schemas/index.ts (external library)
export const Schemas = {
user: z.object({
id: z.number(),
email: z.string().email(),
role: z.enum(["admin", "user"]),
}),
order: z.object({
id: z.string().uuid(),
total: z.number().positive(),
status: z.enum(["pending", "paid", "shipped"]),
}),
};
// Export for global access
export const $$Schemas = Schemas;// In web global script
const userResult = MyTestLib.$$Schemas.user.safeParse(data);
// In web inline code
const isValid = MyTestLib.$$Schemas.order.safeParse($response.body).success;Migration: Web Editor → External Library
Move complex logic from web editor to external library:
Before (Web Editor)
// Complex global script in web editor
class $$PaymentValidator {
static isValidCard(number) {
// Luhn algorithm implementation
let sum = 0;
let isEven = false;
for (let i = number.length - 1; i >= 0; i--) {
let digit = parseInt(number[i], 10);
if (isEven) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
isEven = !isEven;
}
return sum % 10 === 0;
}
// More complex methods...
}After (External Library)
// src/validators/payment.ts
export const isValidCard: AssertionFunction = {
id: "is-valid-card",
name: "Is Valid Card",
enabled: true,
deprecated: false,
tested: true,
function: async (number: string) => {
// Same logic, but now:
// - Version controlled
// - Unit tested
// - TypeScript typed
const isValid = luhnCheck(number);
$addAssertionResult({
passed: isValid,
message: isValid ? "Valid card number" : "Invalid card number",
operator: "isValidCard",
leftValue: number,
rightValue: "valid card",
});
},
};
function luhnCheck(number: string): boolean {
// Implementation with tests
}// Web editor now just references external
class $$PaymentValidator {
static isValidCard(number) {
// Delegate to external library
return MyTestLib.validators.isValidCard(number);
}
}Hybrid Workflow
Recommended approach for teams:
| Component Type | Where to Create | Why |
|---|---|---|
| Simple assertions | Web editor | Quick to create |
| Complex assertions | External library | Needs testing |
| Quick generators | Web editor | One-off use |
| Reusable generators | External library | Shared across projects |
| Simple hooks | Web editor | Basic auth/logging |
| Complex hooks | External library | Encryption, signing |
| Visual tests | Web editor | QA creates these |
| Code-driven tests | External library | Developers create these |
Deprecation Strategy
When moving from web to external:
- Create external version with same functionality
- Mark web version as deprecated (still works, hidden from UI)
- Update existing tests to use external version
- Disable web version after migration complete
// Web version - mark deprecated
{
id: "old-validator",
enabled: true,
deprecated: true, // Hidden from UI, still works
// ...
}