From 2f3698ad7c5d0322b5fce27c4f0a909d96f8d91f Mon Sep 17 00:00:00 2001 From: "boyan.tonchev" Date: Mon, 6 Feb 2023 12:45:21 +0200 Subject: [PATCH] Fixes NPE when language is changed What? From time to time there is an NPE when language is changed. Why? Changing of language is asynchronous process and sometimes changing of language happen before the yasqui is initialized. How? Added a wait function which wait component to be ready. --- cypress/e2e/languages.spec.cy.ts | 14 ++++-- cypress/steps/yasr-steps.ts | 2 +- .../ontotext-yasgui-web-component.tsx | 43 +++++++++++-------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/cypress/e2e/languages.spec.cy.ts b/cypress/e2e/languages.spec.cy.ts index be5538e1..86227f17 100644 --- a/cypress/e2e/languages.spec.cy.ts +++ b/cypress/e2e/languages.spec.cy.ts @@ -58,8 +58,11 @@ describe('Languages', () => { // Then I expect to see error message be translated to English language. YasrSteps.getErrorHeader().contains('Try query in new browser window'); - // When change the language to be French - LanguagesSteps.switchToFr(); + // When change the language to be French + LanguagesSteps.switchToFr(); + // Yasgui re-renders all DOM elements to shows the new labels. This includes the plugins of yasr which is time-consuming. + // We have to wait a bit because cypress is too fast and grabs the old element (with the old label) and the test fails. + cy.wait(500); // Then I expect to see error message be translated to French language. YasrSteps.getErrorHeader().contains('Essayez la requête dans une nouvelle fenêtre du navigateur'); @@ -73,8 +76,11 @@ describe('Languages', () => { // Then I expect to see error message be translated to English language. YasrSteps.getResultFilter().invoke('attr', 'placeholder').should('contain', 'Filter query results'); - // When change the language to be French - LanguagesSteps.switchToFr(); + // When change the language to be French + LanguagesSteps.switchToFr(); + // Yasgui re-renders all DOM elements to shows the new labels. This includes the plugins of yasr which is time-consuming. + // We have to wait a bit because cypress is too fast and grabs the old element (with the old label) and the test fails. + cy.wait(500); // Then I expect yasr to be translated to French. YasrSteps.getResultFilter().invoke('attr', 'placeholder').should('contain', 'Filtrer les résultats des requêtes'); diff --git a/cypress/steps/yasr-steps.ts b/cypress/steps/yasr-steps.ts index a9409f56..cad34f17 100644 --- a/cypress/steps/yasr-steps.ts +++ b/cypress/steps/yasr-steps.ts @@ -8,7 +8,7 @@ export class YasrSteps { } static getErrorHeader() { - return YasrSteps.getResultHeader().get('.errorHeader'); + return cy.get('.errorHeader'); } static getResults() { diff --git a/ontotext-yasgui-web-component/src/components/ontotext-yasgui-web-component/ontotext-yasgui-web-component.tsx b/ontotext-yasgui-web-component/src/components/ontotext-yasgui-web-component/ontotext-yasgui-web-component.tsx index 2dbef57e..ee9ebe28 100644 --- a/ontotext-yasgui-web-component/src/components/ontotext-yasgui-web-component/ontotext-yasgui-web-component.tsx +++ b/ontotext-yasgui-web-component/src/components/ontotext-yasgui-web-component/ontotext-yasgui-web-component.tsx @@ -173,7 +173,10 @@ export class OntotextYasguiWebComponent { @Watch('language') languageChanged(newLang: string) { this.translationService.setLanguage(newLang); - this.ontotextYasgui.refresh(); + this.getOntotextYasgui() + .then((ontotextYasgui) => { + ontotextYasgui.refresh(); + }); } /** @@ -182,8 +185,8 @@ export class OntotextYasguiWebComponent { */ @Method() setQuery(query: string): Promise { - this.ontotextYasgui.setQuery(query); - return Promise.resolve(); + return this.getOntotextYasgui() + .then(() => this.ontotextYasgui.setQuery(query)); } /** @@ -198,21 +201,8 @@ export class OntotextYasguiWebComponent { // for handling the fact that there is a chance for the client to hit the problem where when the // OntotextYasgui instance is created and returned the wrapped Yasgui instance might not be yet // initialized. - return new Promise((resolve, reject) => { - let maxIterationsToComplete = 15; - const timer = setInterval(() => { - maxIterationsToComplete--; - if (this.ontotextYasgui.getInstance()) { - this.ontotextYasgui.openTab(queryModel); - clearInterval(timer); - return resolve(); - } - if (maxIterationsToComplete === 0) { - clearInterval(timer); - return reject(`Can't initialize Yasgui!`); - } - }, 100); - }); + return this.getOntotextYasgui() + .then(ontotextYasgui => ontotextYasgui.openTab(queryModel)); } /** @@ -614,6 +604,23 @@ export class OntotextYasguiWebComponent { } } + private getOntotextYasgui(): Promise { + return new Promise((resolve, reject) => { + let maxIterationsToComplete = 15; + const timer = setInterval(() => { + maxIterationsToComplete--; + if (this.ontotextYasgui && this.ontotextYasgui.getInstance()) { + clearInterval(timer); + return resolve(this.ontotextYasgui); + } + if (maxIterationsToComplete === 0) { + clearInterval(timer); + return reject(`Can't initialize Yasgui!`); + } + }, 100); + }); + } + private destroy() { if (this.ontotextYasgui) { this.ontotextYasgui.destroy();