mirror of
https://github.com/mattermost/mattermost-mobile.git
synced 2026-11-13 06:30:29 +00:00
fix(e2e): stabilize Detox and Maestro test suite Restore main features, and harden the E2E harness against flaky UI, network, retry, synchronization, and classification-lock failures. Stabilize channel creation, saved messages, bookmarks, search, deep links, keyboard dismissal, and post verification. Bound network, transport, health-check, synchronization, and lock retries by elapsed time. Fix iOS and Android Maestro/Detox races and flaky interaction flows. Restore Session Attributes and deep-link fixes lost during merge. Improve test isolation, global-setting cleanup, and Jest/TSIO reporting. Enforce Maestro flow-header validation in local and CI checks.
90 lines
3.8 KiB
TypeScript
90 lines
3.8 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import {isIos, timeouts, wait, waitForElementToExist, waitForElementToNotExist, withSynchronizationDisabled} from '@support/utils';
|
|
import {expect, waitFor} from 'detox';
|
|
|
|
class ThreadOptionsScreen {
|
|
testID = {
|
|
threadOptionsScreen: 'thread_options.screen',
|
|
replyThreadOption: 'post_options.reply_post.option',
|
|
followThreadOption: 'post_options.follow_thread.option',
|
|
followingThreadOption: 'post_options.following_thread.option',
|
|
openInChannelOption: 'thread_options.open_in_channel.option',
|
|
markAsReadOption: 'thread_options.mark_as_read.option',
|
|
markAsUnreadOption: 'thread_options.mark_as_unread.option',
|
|
saveThreadOption: 'post_options.Save_post.option',
|
|
unsaveThreadOption: 'post_options.Unsave_post.option',
|
|
copyLinkOption: 'post_options.copy_permalink.option',
|
|
};
|
|
|
|
threadOptionsScreen = element(by.id(this.testID.threadOptionsScreen));
|
|
replyThreadOption = element(by.id(this.testID.replyThreadOption));
|
|
followThreadOption = element(by.id(this.testID.followThreadOption));
|
|
followingThreadOption = element(by.id(this.testID.followingThreadOption));
|
|
openInChannelOption = element(by.id(this.testID.openInChannelOption));
|
|
markAsReadOption = element(by.id(this.testID.markAsReadOption));
|
|
markAsUnreadOption = element(by.id(this.testID.markAsUnreadOption));
|
|
saveThreadOption = element(by.id(this.testID.saveThreadOption));
|
|
unsaveThreadOption = element(by.id(this.testID.unsaveThreadOption));
|
|
copyLinkOption = element(by.id(this.testID.copyLinkOption));
|
|
|
|
toBeVisible = async () => {
|
|
await waitForElementToExist(this.threadOptionsScreen, timeouts.TEN_SEC);
|
|
|
|
return threadOptionsScreen;
|
|
};
|
|
|
|
close = async () => {
|
|
if (isIos()) {
|
|
await this.threadOptionsScreen.swipe('down');
|
|
} else {
|
|
await device.pressBack();
|
|
}
|
|
await wait(timeouts.ONE_SEC);
|
|
await expect(this.threadOptionsScreen).not.toBeVisible();
|
|
await wait(timeouts.ONE_SEC);
|
|
};
|
|
|
|
// Same gorhom+Reanimated path as PostOptionsScreen.tapSheetRowIos: center taps miss
|
|
// the Save row on iOS 26, and Detox sync never idles so waitFor cannot see dismiss.
|
|
private tapSheetRowIos = async (option: Detox.NativeElement) => {
|
|
await withSynchronizationDisabled(async () => {
|
|
await waitForElementToExist(this.threadOptionsScreen, timeouts.TEN_SEC);
|
|
await waitForElementToExist(option, timeouts.TEN_SEC);
|
|
await option.tap({x: 1, y: 1});
|
|
try {
|
|
await waitForElementToNotExist(this.threadOptionsScreen, timeouts.FIVE_SEC);
|
|
} catch {
|
|
await option.tap({x: 1, y: 1});
|
|
await waitForElementToNotExist(this.threadOptionsScreen, timeouts.FIVE_SEC);
|
|
}
|
|
});
|
|
};
|
|
|
|
tapSaveThread = async () => {
|
|
if (isIos()) {
|
|
await this.tapSheetRowIos(this.saveThreadOption);
|
|
return;
|
|
}
|
|
await this.toBeVisible();
|
|
await waitFor(this.saveThreadOption).toExist().withTimeout(timeouts.FIVE_SEC);
|
|
await this.saveThreadOption.tap();
|
|
await waitFor(this.threadOptionsScreen).not.toExist().withTimeout(timeouts.TEN_SEC);
|
|
};
|
|
|
|
tapUnsaveThread = async () => {
|
|
if (isIos()) {
|
|
await this.tapSheetRowIos(this.unsaveThreadOption);
|
|
return;
|
|
}
|
|
await this.toBeVisible();
|
|
await waitFor(this.unsaveThreadOption).toExist().withTimeout(timeouts.FIVE_SEC);
|
|
await this.unsaveThreadOption.tap();
|
|
await waitFor(this.threadOptionsScreen).not.toExist().withTimeout(timeouts.TEN_SEC);
|
|
};
|
|
}
|
|
|
|
const threadOptionsScreen = new ThreadOptionsScreen();
|
|
export default threadOptionsScreen;
|