Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][Fuctional Test] Make setDefaultAbsoluteRange more robust and update doc views tests #5242

Merged
merged 2 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Data Explorer][Discover] Allow data grid to auto adjust size based on fetched data count ([#5191](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5191))
- [BUG] Fix wrong test due to time conversion ([#5174](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5174))
- [BUG][Data Explorer][Discover] Allow filter and query persist when refresh page or paste url to a new tab ([#5206](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5206))
- [BUG][Fuctional Test] Make setDefaultAbsoluteRange more robust and update doc views tests ([#5242](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5242))

### 🚞 Infrastructure

Expand Down
78 changes: 78 additions & 0 deletions test/functional/page_objects/time_picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function TimePickerProvider({ getService, getPageObjects }: FtrProviderCo
const { header } = getPageObjects(['header']);
const opensearchDashboardsServer = getService('opensearchDashboardsServer');
const MenuToggle = getService('MenuToggle');
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const quickSelectTimeMenuToggle = new MenuToggle({
name: 'QuickSelectTime Menu',
Expand Down Expand Up @@ -309,6 +310,83 @@ export function TimePickerProvider({ getService, getPageObjects }: FtrProviderCo
const toTime = 'Apr 13, 2018 @ 00:00:00.000';
await this.setAbsoluteRange(fromTime, toTime);
}

// Helper function to set input value and verify
private async setInputValueWithRetry(testSubjectId: string, value: string) {
const MAX_ATTEMPTS = 3;

for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
// try to set the value
await this.inputValue(testSubjectId, value);
await sleep(500);

// verify if the value was correctly set
const actualValue = await (await testSubjects.find(testSubjectId)).getAttribute('value');
if (actualValue === value) {
return;
}

// if it's the last attempt and value wasn't set correctly, throw an error
if (attempt === MAX_ATTEMPTS - 1) {
throw new Error(
`Failed to set ${testSubjectId} to ${value} after ${MAX_ATTEMPTS} attempts.`
);
}

await sleep(500); // wait before retrying
}
}

// TODO: This is a temporary method added due to observed issues with panels
// not closing in time and incorrect time settings on Discover page. Once these bugs are resolved
// and the interactions become more reliable, we should consider removing this method and related helper functions.
// Tracking issue: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/5241
/**
* @param {String} fromTime MMM D, YYYY @ HH:mm:ss.SSS
* @param {String} toTime MMM D, YYYY @ HH:mm:ss.SSS
*/
public async setDefaultRangeForDiscover() {
const fromTime = this.defaultStartTime;
const toTime = this.defaultEndTime;
log.debug(`Setting absolute range to ${fromTime} to ${toTime}`);

await this.showStartEndTimes();
// make sure to close this verify panel
await browser.pressKeys(browser.keys.ESCAPE);
await sleep(500);

// set to time
await testSubjects.click('superDatePickerendDatePopoverButton');
let panel = await this.getTimePickerPanel();
await testSubjects.click('superDatePickerAbsoluteTab');
await testSubjects.click('superDatePickerAbsoluteDateInput');
await this.setInputValueWithRetry('superDatePickerAbsoluteDateInput', toTime);
await browser.pressKeys(browser.keys.ESCAPE); // close popover because sometimes browser can't find start input

// set from time
await testSubjects.click('superDatePickerstartDatePopoverButton');
await this.waitPanelIsGone(panel);
panel = await this.getTimePickerPanel();
await testSubjects.click('superDatePickerAbsoluteTab');
await testSubjects.click('superDatePickerAbsoluteDateInput');
await this.setInputValueWithRetry('superDatePickerAbsoluteDateInput', fromTime);
await browser.pressKeys(browser.keys.ESCAPE);

const superDatePickerApplyButtonExists = await testSubjects.exists(
'superDatePickerApplyTimeButton'
);
if (superDatePickerApplyButtonExists) {
// Timepicker is in top nav
// Click super date picker apply button to apply time range
await testSubjects.click('superDatePickerApplyTimeButton');
} else {
// Timepicker is embedded in query bar
// click query bar submit button to apply time range
await testSubjects.click('querySubmitButton');
}
await this.waitPanelIsGone(panel);
await header.awaitGlobalLoadingIndicatorHidden();
}
}

return new TimePicker();
Expand Down
6 changes: 4 additions & 2 deletions test/plugin_functional/test_suites/doc_views/doc_views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
describe('custom doc views', function () {
before(async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setDefaultAbsoluteRange();
// TODO: change back to setDefaultRange() once we resolve
// https://github.com/opensearch-project/OpenSearch-Dashboards/issues/5241
await PageObjects.timePicker.setDefaultRangeForDiscover();
});

it('should show custom doc views', async () => {
await testSubjects.click('docTableExpandToggleColumn');
await testSubjects.click('docTableExpandToggleColumn-0');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, yeah looks like we added an index which imo is better for more consistent tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we have to. since we adopt data grid, we have docTableExpandToggleColumn-[row index] now.

const reactTab = await find.byButtonText('React doc view');
expect(await reactTab.isDisplayed()).to.be(true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,83 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
const find = getService('find');
const browser = getService('browser');
const PageObjects = getPageObjects(['common', 'discover', 'timePicker']);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const waitFor = async (conditionFunction, timeoutMs = 10000, intervalMs = 100) => {
const start = Date.now();

let lastError;
while (Date.now() - start < timeoutMs) {
try {
if (await conditionFunction()) {
return;
}
} catch (error) {
lastError = error;
}

await sleep(intervalMs);
}

throw new Error(
`waitFor condition did not become true within ${timeoutMs}ms. Last error: ${
lastError && lastError.message
}`
);
};

describe('custom doc views links', function () {
beforeEach(async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setDefaultAbsoluteRange();
await testSubjects.click('docTableExpandToggleColumn');
// TODO: change back to setDefaultRange() once we resolve
// https://github.com/opensearch-project/OpenSearch-Dashboards/issues/5241
await PageObjects.timePicker.setDefaultRangeForDiscover();
await testSubjects.click('docTableExpandToggleColumn-0');
});

it('should show href and generateCb doc views link', async () => {
it('should show href and generateCb doc views link and not show generateCbHidden doc views link', async () => {
const hrefLink = await find.byLinkText('href doc view link');
const generateCbLink = await find.byLinkText('generateCb doc view link');

expect(await hrefLink.isDisplayed()).to.be(true);
expect(await generateCbLink.isDisplayed()).to.be(true);
});

it('should not render generateCbHidden doc views link', async () => {
expect(await find.existsByLinkText('generateCbHidden doc view link')).to.eql(false);
});

it('should render href doc view link', async () => {
const hrefLink = await find.byLinkText('href doc view link');
const originalTabCount = (await browser.getAllWindowHandles()).length;
await hrefLink.click();
expect(await browser.getCurrentUrl()).to.eql('http://some-url/');

// wait until a new tab is opened
await waitFor(async () => (await browser.getAllWindowHandles()).length > originalTabCount);

// switch to the originalTabCount in case previous tab is not closed in time
await browser.switchTab(originalTabCount);

const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.eql('http://some-url/');

// close new tab and switch back to original tab
await browser.closeCurrentWindow();
await browser.switchTab(0);
});

it('should render generateCb doc view link', async () => {
const generateCbLink = await find.byLinkText('generateCb doc view link');
const originalTabCount = (await browser.getAllWindowHandles()).length;
await generateCbLink.click();
expect(await browser.getCurrentUrl()).to.eql('http://some-url/');

// wait until a new tab is opened
await waitFor(async () => (await browser.getAllWindowHandles()).length > originalTabCount);

// switch to the originalTabCount in case previous tab is not closed in time
await browser.switchTab(originalTabCount);

const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.eql('http://some-url/');

// close new tab and switch back to original tab
await browser.closeCurrentWindow();
await browser.switchTab(0);
});
});
}
Loading