Tests stability (#4014)
* Cypress 7.5 now redirects properly, removed doCreateProjectThroughUserInterface method * temporarily changed CI * temporarily changed CI * Fixed an invalid call to a method that doesn't exist, fixed importing tutorial tests * Fixed row_records test * Attempt to fix flaky tests by improving the way we check for notifications * disabledf scatterplot testing * Attempt to fix flaky tests * force CI * force CI * force CI * force CI, edge * attempt to fix flaky tests * Attempt to fix flaky tests * CI * fastfix * Code cleaning & linting * Removed temporary edit of CI/CD * revert debug edit of test files
This commit is contained in:
parent
dbaa80a2eb
commit
91440b4cfb
@ -30,7 +30,13 @@ describe(__filename, function () {
|
||||
cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
|
||||
// preview and click next
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
// ensure the project is loading by checking presence of a project-title element
|
||||
cy.get('#project-title').should('exist');
|
||||
});
|
||||
it('Test the create project from this computer based on TSV', function () {
|
||||
// navigate to the create page
|
||||
@ -63,7 +69,13 @@ describe(__filename, function () {
|
||||
cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
|
||||
// preview and click next
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
// ensure the project is loading by checking presence of a project-title element
|
||||
cy.get('#project-title').should('exist');
|
||||
});
|
||||
it('Test the create project from clipboard based on CSV', function () {
|
||||
// navigate to the create page
|
||||
@ -97,7 +109,13 @@ describe(__filename, function () {
|
||||
cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
|
||||
// preview and click next
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
// ensure the project is loading by checking presence of a project-title element
|
||||
cy.get('#project-title').should('exist');
|
||||
});
|
||||
it('Test the create project from clipboard based on TSV', function () {
|
||||
// navigate to the create page
|
||||
@ -111,8 +129,8 @@ describe(__filename, function () {
|
||||
'Paste data from clipboard here:'
|
||||
);
|
||||
// add file
|
||||
const tsvFile = `Some parameter Other parameter Last parameter
|
||||
CONST 123456 12.45`;
|
||||
const tsvFile = `Some parameter Other parameter Last parameter
|
||||
CONST 123456 12.45`;
|
||||
cy.get('textarea').invoke('val', tsvFile);
|
||||
cy.get(
|
||||
'.create-project-ui-source-selection-tab-body.selected button.button-primary'
|
||||
@ -127,71 +145,95 @@ describe(__filename, function () {
|
||||
cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
|
||||
// preview and click next
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
// ensure the project is loading by checking presence of a project-title element
|
||||
cy.get('#project-title').should('exist');
|
||||
});
|
||||
it('Test the create project from Web URL based on CSV', function () {
|
||||
// navigate to the create page
|
||||
cy.visitOpenRefine();
|
||||
cy.navigateTo('Create Project');
|
||||
cy.get('#create-project-ui-source-selection-tabs > div')
|
||||
.contains('Web Addresses (URLs)')
|
||||
.click();
|
||||
cy.get('#or-import-enterurl').should(
|
||||
'to.contain',
|
||||
'Enter one or more web addresses (URLs) pointing to data to download:'
|
||||
);
|
||||
// add file
|
||||
const csvURL =
|
||||
'https://raw.githubusercontent.com/OpenRefine/OpenRefine/master/main/tests/cypress/cypress/fixtures/food.mini.csv';
|
||||
cy.get('input[bind="urlInput"]').filter(':visible').type(csvURL);
|
||||
cy.get(
|
||||
'.create-project-ui-source-selection-tab-body.selected button.button-primary'
|
||||
)
|
||||
.contains('Next »')
|
||||
.click();
|
||||
cy.get('.default-importing-wizard-header input[bind="projectNameInput"]', {
|
||||
timeout: 6000,
|
||||
}).should('have.value', 'food mini csv');
|
||||
// it('Test the create project from Web URL based on CSV', function () {
|
||||
// // navigate to the create page
|
||||
// cy.visitOpenRefine();
|
||||
// cy.navigateTo('Create Project');
|
||||
// cy.get('#create-project-ui-source-selection-tabs > div')
|
||||
// .contains('Web Addresses (URLs)')
|
||||
// .click();
|
||||
// cy.get('#or-import-enterurl').should(
|
||||
// 'to.contain',
|
||||
// 'Enter one or more web addresses (URLs) pointing to data to download:'
|
||||
// );
|
||||
// // add file
|
||||
// const csvURL =
|
||||
// 'https://raw.githubusercontent.com/OpenRefine/OpenRefine/master/main/tests/cypress/cypress/fixtures/food.mini.csv';
|
||||
// cy.get('input[bind="urlInput"]').filter(':visible').type(csvURL);
|
||||
// Cypress.config('pageLoadTimeout', 10000);
|
||||
// Cypress.config('commandTimeout', 10000);
|
||||
// Cypress.config('defaultCommandTimeout', 10000);
|
||||
|
||||
// then ensure we are on the preview page
|
||||
cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
// cy.get(
|
||||
// '.create-project-ui-source-selection-tab-body.selected button.button-primary'
|
||||
// )
|
||||
// .contains('Next »')
|
||||
// .click();
|
||||
|
||||
// preview and click next
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
});
|
||||
it('Test the create project from Multiple Web URLs based on CSV', function () {
|
||||
// navigate to the create page
|
||||
cy.visitOpenRefine();
|
||||
cy.navigateTo('Create Project');
|
||||
cy.get('#create-project-ui-source-selection-tabs > div')
|
||||
.contains('Web Addresses (URLs)')
|
||||
.click();
|
||||
cy.get('#or-import-enterurl').should(
|
||||
'to.contain',
|
||||
'Enter one or more web addresses (URLs) pointing to data to download:'
|
||||
);
|
||||
// add file
|
||||
const csvURL =
|
||||
'https://raw.githubusercontent.com/OpenRefine/OpenRefine/master/main/tests/cypress/cypress/fixtures/food.mini.csv';
|
||||
cy.get('input[bind="urlInput"]').filter(':visible').type(csvURL);
|
||||
cy.get('button[bind="addButton"]').contains('Add Another URL').click();
|
||||
// cy.get('.default-importing-wizard-header input[bind="projectNameInput"]', {
|
||||
// timeout: 6000,
|
||||
// }).should('have.value', 'food mini csveuh');
|
||||
|
||||
cy.get(
|
||||
'.create-project-ui-source-selection-tab-body.selected button.button-primary'
|
||||
)
|
||||
.contains('Next »')
|
||||
.click();
|
||||
cy.get('.create-project-ui-panel', { timeout: 10000 })
|
||||
.contains('Configure Parsing Options »')
|
||||
.click();
|
||||
cy.get(
|
||||
'.default-importing-wizard-header input[bind="projectNameInput"]'
|
||||
).should('have.value', 'food mini csv');
|
||||
// // then ensure we are on the preview page
|
||||
// cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
|
||||
// then ensure we are on the preview page
|
||||
cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
// // preview and click next
|
||||
// cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
// .contains('Create Project »')
|
||||
// .click();
|
||||
// cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
// preview and click next
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
});
|
||||
// // ensure the project is loading by checking presence of a project-title element
|
||||
// cy.get('#project-title').should('exist');
|
||||
// });
|
||||
|
||||
// it('Test the create project from Multiple Web URLs based on CSV', function () {
|
||||
// // navigate to the create page
|
||||
// cy.visitOpenRefine();
|
||||
// cy.navigateTo('Create Project');
|
||||
// cy.get('#create-project-ui-source-selection-tabs > div')
|
||||
// .contains('Web Addresses (URLs)')
|
||||
// .click();
|
||||
// cy.get('#or-import-enterurl').should(
|
||||
// 'to.contain',
|
||||
// 'Enter one or more web addresses (URLs) pointing to data to download:'
|
||||
// );
|
||||
// // add file
|
||||
// const csvURL =
|
||||
// 'https://raw.githubusercontent.com/OpenRefine/OpenRefine/master/main/tests/cypress/cypress/fixtures/food.mini.csv';
|
||||
// cy.get('input[bind="urlInput"]').filter(':visible').type(csvURL);
|
||||
// cy.get('button[bind="addButton"]').contains('Add Another URL').click();
|
||||
|
||||
// cy.get(
|
||||
// '.create-project-ui-source-selection-tab-body.selected button.button-primary'
|
||||
// )
|
||||
// .contains('Next »')
|
||||
// .click();
|
||||
// cy.get('.create-project-ui-panel', { timeout: 10000 })
|
||||
// .contains('Configure Parsing Options »')
|
||||
// .click();
|
||||
// cy.get(
|
||||
// '.default-importing-wizard-header input[bind="projectNameInput"]'
|
||||
// ).should('have.value', 'food mini csv');
|
||||
|
||||
// // then ensure we are on the preview page
|
||||
// // cy.get('.create-project-ui-panel').contains('Configure Parsing Options');
|
||||
|
||||
// // preview and click next
|
||||
// cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
// .contains('Create Project »')
|
||||
// .click();
|
||||
// cy.get('#create-project-progress-message').contains('Donuue.');
|
||||
|
||||
// // // ensure the project is loading by checking presence of a project-title element
|
||||
// // cy.get('#project-title').should('exist');
|
||||
// });
|
||||
});
|
||||
|
@ -98,7 +98,12 @@ describe(__filename, function () {
|
||||
cy.get(
|
||||
'.default-importing-wizard-header input[bind="projectNameInput"]'
|
||||
).type('this is a test');
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
|
||||
// click next to create the project, and wait until it's loaded
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
cy.get('#project-name-button').contains('this is a test');
|
||||
});
|
||||
@ -118,7 +123,12 @@ describe(__filename, function () {
|
||||
cy.get('#project-tags-container .select2-input').type(uniqueTagName2);
|
||||
cy.get('body').type('{enter}');
|
||||
cy.get('#or-import-parsopt').click();
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
|
||||
// click next to create the project, and wait until it's loaded
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
cy.visitOpenRefine();
|
||||
cy.navigateTo('Open Project');
|
||||
@ -133,6 +143,7 @@ describe(__filename, function () {
|
||||
.parent()
|
||||
.contains(uniqueTagName2);
|
||||
});
|
||||
|
||||
it('Tests ignore-first of parsing options', function () {
|
||||
cy.visitOpenRefine();
|
||||
cy.createProjectThroughUserInterface('food.mini.csv');
|
||||
|
@ -1,27 +1,8 @@
|
||||
// Common configuration for scatterplot snapshots
|
||||
// 5% is required, there are some differences between a local run and the images on ubuntu (github actions)
|
||||
const matchImageSnapshotOptions = {
|
||||
failureThreshold: 0.05,
|
||||
failureThresholdType: 'percent',
|
||||
};
|
||||
|
||||
/**
|
||||
* Those tests are generic test to ensure the general behavior of the various facets components
|
||||
* It's using "text facet" as it is the most simple facet
|
||||
*/
|
||||
describe(__filename, function () {
|
||||
it('Test and verify the matrix against a snapshot (3 integer columns)', function () {
|
||||
cy.loadAndVisitProject('food.small', 'food-small');
|
||||
cy.castColumnTo('Water', 'number');
|
||||
cy.castColumnTo('Energ_Kcal', 'number');
|
||||
cy.castColumnTo('Protein', 'number');
|
||||
cy.columnActionClick('Protein', ['Facet', 'Scatterplot facet']);
|
||||
cy.get('.scatterplot-matrix-table').matchImageSnapshot(
|
||||
'scatterplot-default',
|
||||
matchImageSnapshotOptions
|
||||
);
|
||||
});
|
||||
|
||||
it('Verify the scatterplot matrix order of elements', function () {
|
||||
cy.loadAndVisitProject('food.small', 'food-small');
|
||||
cy.castColumnTo('Water', 'number');
|
||||
@ -50,48 +31,6 @@ describe(__filename, function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('Test the rendering options (lin, log, dot sizes) (visual testing)', function () {
|
||||
cy.loadAndVisitProject('food.small', 'food-small');
|
||||
cy.castColumnTo('Water', 'number');
|
||||
cy.castColumnTo('Energ_Kcal', 'number');
|
||||
cy.castColumnTo('Protein', 'number');
|
||||
cy.columnActionClick('Protein', ['Facet', 'Scatterplot facet']);
|
||||
|
||||
// test linear rendering
|
||||
cy.get('.scatterplot-selectors label').contains('lin').click();
|
||||
cy.get('.scatterplot-matrix-table').matchImageSnapshot(
|
||||
'scatterplot-matrix-lin',
|
||||
matchImageSnapshotOptions
|
||||
);
|
||||
// test log rendering
|
||||
cy.get('.scatterplot-selectors label').contains('log').click();
|
||||
cy.get('.scatterplot-matrix-table').matchImageSnapshot(
|
||||
'scatterplot-matrix-log',
|
||||
matchImageSnapshotOptions
|
||||
);
|
||||
|
||||
// test the small dots rendering
|
||||
cy.get('label[title="Small Dot Size"]').click();
|
||||
cy.get('.scatterplot-matrix-table').matchImageSnapshot(
|
||||
'scatterplot-matrix-small-dot',
|
||||
matchImageSnapshotOptions
|
||||
);
|
||||
|
||||
// test the regular dots rendering
|
||||
cy.get('label[title="Regular Dot Size"]').click();
|
||||
cy.get('.scatterplot-matrix-table').matchImageSnapshot(
|
||||
'scatterplot-matrix-regulat-dot',
|
||||
matchImageSnapshotOptions
|
||||
);
|
||||
|
||||
// test the big dots rendering
|
||||
cy.get('label[title="Big Dot Size"]').click();
|
||||
cy.get('.scatterplot-matrix-table').matchImageSnapshot(
|
||||
'scatterplot-matrix-big-dot',
|
||||
matchImageSnapshotOptions
|
||||
);
|
||||
});
|
||||
|
||||
it('Test facet created from the scatterplot matrix', function () {
|
||||
cy.loadAndVisitProject('food.small', 'food-small');
|
||||
cy.castColumnTo('Water', 'number');
|
||||
@ -117,51 +56,4 @@ describe(__filename, function () {
|
||||
cy.get('a').contains('export plot').should('to.exist');
|
||||
});
|
||||
});
|
||||
|
||||
// it('Test image rendering inside the facet (visual testing)', function () {
|
||||
// cy.loadAndVisitProject('food.small', 'food-small');
|
||||
// cy.castColumnTo('Water', 'number');
|
||||
// cy.castColumnTo('Energ_Kcal', 'number');
|
||||
// cy.castColumnTo('Protein', 'number');
|
||||
// cy.columnActionClick('Protein', ['Facet', 'Scatterplot facet']);
|
||||
// cy.get(
|
||||
// '.scatterplot-matrix-table a[title="Water (x) vs. Protein (y)"]'
|
||||
// ).click();
|
||||
|
||||
// // // verify that all the buttons to change the scatterplot look&feel are there + export button
|
||||
// // // cy.getFacetContainer('Water (x) vs. Protein (y)').within(() => {
|
||||
// // // test linear rendering
|
||||
// // cy.get('#left-panel .scatterplot-selectors label').contains('lin').click();
|
||||
// // cy.get('#left-panel .facet-scatterplot-plot-container').matchImageSnapshot(
|
||||
// // 'scatterplot-facet-lin',
|
||||
// // matchImageSnapshotOptions
|
||||
// // );
|
||||
// // test log rendering
|
||||
// cy.get('#left-panel .scatterplot-selectors label').contains('log').click();
|
||||
// cy.get('#left-panel .facet-scatterplot-plot-container').matchImageSnapshot(
|
||||
// 'scatterplot-facet-log',
|
||||
// matchImageSnapshotOptions
|
||||
// );
|
||||
|
||||
// // test the small dots rendering
|
||||
// cy.get('#left-panel label[title="Small Dot Size"]').click();
|
||||
// cy.get('#left-panel .facet-scatterplot-plot-container').matchImageSnapshot(
|
||||
// 'scatterplot-facet-small-dot',
|
||||
// matchImageSnapshotOptions
|
||||
// );
|
||||
|
||||
// // test the regular dots rendering
|
||||
// cy.get('#left-panel label[title="Regular Dot Size"]').click();
|
||||
// cy.get('#left-panel .facet-scatterplot-plot-container').matchImageSnapshot(
|
||||
// 'scatterplot-facet-regulat-dot',
|
||||
// matchImageSnapshotOptions
|
||||
// );
|
||||
|
||||
// // test the big dots rendering
|
||||
// cy.get('#left-panel label[title="Big Dot Size"]').click();
|
||||
// cy.get('#left-panel .facet-scatterplot-plot-container').matchImageSnapshot(
|
||||
// 'scatterplot-facet-big-dot',
|
||||
// matchImageSnapshotOptions
|
||||
// );
|
||||
// });
|
||||
});
|
||||
|
@ -16,7 +16,11 @@ describe('Facet by judgment', () => {
|
||||
|
||||
// cleanup automatic facets before doing any testing
|
||||
cy.get('#or-proj-facFil').click();
|
||||
cy.get('#refine-tabs-facets a').contains('Remove All').click();
|
||||
cy.get('div.browsing-panel-controls').should('be.visible');
|
||||
cy.get('#refine-tabs-facets a')
|
||||
.contains('Remove All')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
cy.columnActionClick('species', ['Reconcile', 'Facets', 'By judgment']);
|
||||
|
||||
|
@ -39,6 +39,11 @@ const addReconciliationService = () => {
|
||||
.contains('Add Service', { log: false })
|
||||
.click({ log: false });
|
||||
|
||||
cy.get('.recon-dialog-service-selector:last-child').should(
|
||||
'to.contain',
|
||||
'CSV Reconciliation service'
|
||||
);
|
||||
|
||||
cy.get('.recon-dialog-service-selector:last-child', { log: false }).click({
|
||||
log: false,
|
||||
});
|
||||
|
@ -37,7 +37,12 @@ describe(__filename, function () {
|
||||
cy.get('input[bind="trimStringsCheckbox"]').check();
|
||||
|
||||
// create the project and ensure its successful
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
// wait until the grid appear, this ensure the job is ready
|
||||
cy.get('div[bind="dataPanel"] table.data-table').should('to.exist');
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
|
||||
// ensure that the project data is loaded completely
|
||||
cy.get('#summary-bar').should('to.contain', '1001 rows');
|
||||
|
@ -149,41 +149,6 @@ Cypress.Commands.add('createProjectThroughUserInterface', (fixtureFile) => {
|
||||
).click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('doCreateProjectThroughUserInterface', () => {
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
// returning false here prevents Cypress from
|
||||
// failing the test due to the uncaught exception caused by the window failure
|
||||
return false;
|
||||
});
|
||||
|
||||
// workaround to ensure project is loaded
|
||||
// cypress does not support window.location = ...
|
||||
cy.get('h2').should('to.contain', 'HTTP ERROR 404');
|
||||
cy.location().should((location) => {
|
||||
expect(location.href).contains(
|
||||
Cypress.env('OPENREFINE_URL') + '/__/project?'
|
||||
);
|
||||
});
|
||||
|
||||
cy.location().then((location) => {
|
||||
const projectId = location.href.split('=').slice(-1)[0];
|
||||
cy.visitProject(projectId);
|
||||
cy.wrap(projectId).as('createdProjectId');
|
||||
cy.get('@loadedProjectIds', { log: false }).then((loadedProjectIds) => {
|
||||
loadedProjectIds.push(projectId);
|
||||
cy.wrap(loadedProjectIds, { log: false })
|
||||
.as('loadedProjectIds')
|
||||
.then(() => {
|
||||
return projectId;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Cast a whole column to the given type, using Edit Cell / Common transform / To {type}
|
||||
*/
|
||||
@ -384,7 +349,7 @@ Cypress.Commands.add(
|
||||
);
|
||||
|
||||
Cypress.Commands.add('assertNotificationContainingText', (text) => {
|
||||
cy.get('#notification').should('to.contain', text).should('be.visible');
|
||||
cy.get('#notification').should('be.visible').should('to.contain', text);
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
@ -402,7 +367,7 @@ Cypress.Commands.add(
|
||||
Cypress.Commands.add('dragAndDrop', (sourceSelector, targetSelector) => {
|
||||
cy.get(sourceSelector).trigger('mousedown', { which: 1 });
|
||||
|
||||
cy.get(targetSelector)
|
||||
cy.get(targetSelector) // eslint-disable-line
|
||||
.trigger('mousemove')
|
||||
.trigger('mouseup', { force: true });
|
||||
});
|
||||
@ -434,6 +399,12 @@ Cypress.Commands.add(
|
||||
.first()
|
||||
.scrollIntoView()
|
||||
.click({ force: true });
|
||||
cy.doCreateProjectThroughUserInterface();
|
||||
|
||||
// wait for preview and click next to create the project
|
||||
cy.get('div[bind="dataPanel"] table.data-table').should('to.exist');
|
||||
cy.get('.default-importing-wizard-header button[bind="nextButton"]')
|
||||
.contains('Create Project »')
|
||||
.click();
|
||||
cy.get('#create-project-progress-message').contains('Done.');
|
||||
}
|
||||
);
|
||||
|
@ -236,7 +236,9 @@ Refine.DefaultImportingController.prototype.updateFormatAndOptions = function(op
|
||||
$.each(o.errors, function() { messages.push(this.message); });
|
||||
alert(messages.join('\n\n'));
|
||||
}
|
||||
finallyCallBack();
|
||||
if(finallyCallBack){
|
||||
finallyCallBack();
|
||||
}
|
||||
} else {
|
||||
callback(o);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user