Handle aborted get requests and null domain objects when using ObjectAPI (#7276)

* handle null domain objects

* add some test coverage for aborting search results

* to make test independent
This commit is contained in:
Scott Bell 2023-12-05 18:43:49 +01:00 committed by GitHub
parent 2d9c0414f7
commit 93e5219917
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 3 deletions

View File

@ -198,6 +198,32 @@ test.describe('Grand Search', () => {
await expect(searchResultDropDown).toContainText('Clock A');
});
test('Slowly typing after search debounce will abort requests @couchdb', async ({ page }) => {
let requestWasAborted = false;
await createObjectsForSearch(page);
page.on('requestfailed', (request) => {
// check if the request was aborted
if (request.failure().errorText === 'net::ERR_ABORTED') {
requestWasAborted = true;
}
});
// Intercept and delay request
const delayInMs = 100;
await page.route('**', async (route, request) => {
await new Promise((resolve) => setTimeout(resolve, delayInMs));
route.continue();
});
// Slowly type after search delay
const searchInput = page.getByRole('searchbox', { name: 'Search Input' });
await searchInput.pressSequentially('Clock', { delay: 200 });
await expect(page.getByText('Clock B').first()).toBeVisible();
expect(requestWasAborted).toBe(true);
});
test('Validate multiple objects in search results return partial matches', async ({ page }) => {
test.info().annotations.push({
type: 'issue',

View File

@ -232,6 +232,10 @@ export default class ObjectAPI {
.get(identifier, abortSignal)
.then((domainObject) => {
delete this.cache[keystring];
if (!domainObject && abortSignal.aborted) {
// we've aborted the request
return;
}
domainObject = this.applyGetInterceptors(identifier, domainObject);
if (this.supportsMutation(identifier)) {
@ -791,6 +795,9 @@ export default class ObjectAPI {
*/
async getOriginalPath(identifier, path = [], abortSignal = null) {
const domainObject = await this.get(identifier, abortSignal);
if (!domainObject) {
return [];
}
path.push(domainObject);
const { location } = domainObject;
if (location && !this.#pathContainsDomainObject(location, path)) {

View File

@ -180,7 +180,7 @@ define(['uuid'], function ({ v4: uuid }) {
{
check(domainObject) {
return (
domainObject.type === 'layout' &&
domainObject?.type === 'layout' &&
domainObject.configuration &&
domainObject.configuration.layout
);
@ -201,7 +201,7 @@ define(['uuid'], function ({ v4: uuid }) {
{
check(domainObject) {
return (
domainObject.type === 'telemetry.fixed' &&
domainObject?.type === 'telemetry.fixed' &&
domainObject.configuration &&
domainObject.configuration['fixed-display']
);
@ -246,7 +246,7 @@ define(['uuid'], function ({ v4: uuid }) {
{
check(domainObject) {
return (
domainObject.type === 'table' &&
domainObject?.type === 'table' &&
domainObject.configuration &&
domainObject.configuration.table
);