60e2149072
Tasks 16-20: Online Board Tests (Search/Filter, Tabs, Flight List, Details Modal, Time/Date) - Task 16: Search & Filter tests (37 tests) - departure/arrival cities, passenger count, cabin class - Task 17: Arrival/Departure Tabs tests (45 tests) - tab switching, flight display, sorting - Task 18: Flight List View tests (50 tests) - display, sorting, filtering, pagination, loading states - Task 19: Flight Details Modal tests (40 tests) - opening/closing, content display, actions - Task 20: Time & Date Filter tests (43 tests) - date selection, time ranges, calendar navigation Tasks 21-25: Flight Details Tests (Flight Info, Passengers, Seats, Services, Fares) - Task 21: Flight Info Display tests (40 tests) - basic info, airports, route visualization, timeline - Task 22: Passenger Info tests (50 tests) - passenger list, details, services, special requirements - Task 23: Seat Selection tests (50 tests) - seat map, selection, categories, recommendations - Task 24: Service Selection tests (25 tests) - baggage, meals, seats, summary - Task 25: Fare Display tests (55 tests) - fare breakdown, comparisons, discounts, refunds All tests follow AAA pattern and use data-testid selectors matching Angular version. Total: 245 tests across 10 feature suites.
101 lines
2.2 KiB
JavaScript
101 lines
2.2 KiB
JavaScript
var RetryOperation = require('./retry_operation');
|
|
|
|
exports.operation = function(options) {
|
|
var timeouts = exports.timeouts(options);
|
|
return new RetryOperation(timeouts, {
|
|
forever: options && options.forever,
|
|
unref: options && options.unref,
|
|
maxRetryTime: options && options.maxRetryTime
|
|
});
|
|
};
|
|
|
|
exports.timeouts = function(options) {
|
|
if (options instanceof Array) {
|
|
return [].concat(options);
|
|
}
|
|
|
|
var opts = {
|
|
retries: 10,
|
|
factor: 2,
|
|
minTimeout: 1 * 1000,
|
|
maxTimeout: Infinity,
|
|
randomize: false
|
|
};
|
|
for (var key in options) {
|
|
opts[key] = options[key];
|
|
}
|
|
|
|
if (opts.minTimeout > opts.maxTimeout) {
|
|
throw new Error('minTimeout is greater than maxTimeout');
|
|
}
|
|
|
|
var timeouts = [];
|
|
for (var i = 0; i < opts.retries; i++) {
|
|
timeouts.push(this.createTimeout(i, opts));
|
|
}
|
|
|
|
if (options && options.forever && !timeouts.length) {
|
|
timeouts.push(this.createTimeout(i, opts));
|
|
}
|
|
|
|
// sort the array numerically ascending
|
|
timeouts.sort(function(a,b) {
|
|
return a - b;
|
|
});
|
|
|
|
return timeouts;
|
|
};
|
|
|
|
exports.createTimeout = function(attempt, opts) {
|
|
var random = (opts.randomize)
|
|
? (Math.random() + 1)
|
|
: 1;
|
|
|
|
var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
|
|
timeout = Math.min(timeout, opts.maxTimeout);
|
|
|
|
return timeout;
|
|
};
|
|
|
|
exports.wrap = function(obj, options, methods) {
|
|
if (options instanceof Array) {
|
|
methods = options;
|
|
options = null;
|
|
}
|
|
|
|
if (!methods) {
|
|
methods = [];
|
|
for (var key in obj) {
|
|
if (typeof obj[key] === 'function') {
|
|
methods.push(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < methods.length; i++) {
|
|
var method = methods[i];
|
|
var original = obj[method];
|
|
|
|
obj[method] = function retryWrapper(original) {
|
|
var op = exports.operation(options);
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
var callback = args.pop();
|
|
|
|
args.push(function(err) {
|
|
if (op.retry(err)) {
|
|
return;
|
|
}
|
|
if (err) {
|
|
arguments[0] = op.mainError();
|
|
}
|
|
callback.apply(this, arguments);
|
|
});
|
|
|
|
op.attempt(function() {
|
|
original.apply(obj, args);
|
|
});
|
|
}.bind(obj, original);
|
|
obj[method].options = options;
|
|
}
|
|
};
|