Compare commits

..

2 Commits

Author SHA1 Message Date
Elisabeth Kulzer
145464d0b1 Detox: Android - Fix latency related tests. 2023-03-07 22:01:58 +01:00
Elisabeth Kulzer
643f81b316 Detox: Android - fix smoke tests. 2023-03-07 16:23:57 +01:00
35 changed files with 215 additions and 194 deletions

View File

@@ -1,31 +0,0 @@
kind: pipeline
name: default
steps:
- name: permissions
image: alpine/git
commands:
- chmod -R 777 .
- name: build
image: cimg/android:2022.09.2-node
environment:
CIRCLECI: true
NODE_OPTIONS: --max_old_space_size=12000
NODE_ENV: production
BABEL_ENV: production
MATTERMOST_RELEASE_STORE_FILE: /root/mattermost.keystore
MATTERMOST_RELEASE_KEY_ALIAS: mattermost-google-key
MATTERMOST_RELEASE_PASSWORD: 123456
commands:
- 'npm run build:android'
- name: gitea_release
image: plugins/gitea-release
settings:
api_key:
from_secret: drone_release
base_url: https://git.ivasoft.cz
files: '*.apk'
when:
event: tag

View File

@@ -110,7 +110,7 @@ android {
applicationId "com.mattermost.rnbeta"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 461
versionCode 460
versionName "2.1.0"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

Binary file not shown.

View File

@@ -6,7 +6,7 @@ import {Platform} from 'react-native';
import {WebsocketEvents} from '@constants';
import DatabaseManager from '@database/manager';
import {getConfigValue} from '@queries/servers/system';
import {getConfig} from '@queries/servers/system';
import {hasReliableWebsocket} from '@utils/config';
import {toMilliseconds} from '@utils/datetime';
import {logError, logInfo, logWarning} from '@utils/log';
@@ -79,12 +79,8 @@ export default class WebSocketClient {
return;
}
const [websocketUrl, version, reliableWebsocketConfig] = await Promise.all([
getConfigValue(database, 'WebsocketURL'),
getConfigValue(database, 'Version'),
getConfigValue(database, 'EnableReliableWebSockets'),
]);
const connectionUrl = (websocketUrl || this.serverUrl) + '/api/v4/websocket';
const config = await getConfig(database);
const connectionUrl = (config.WebsocketURL || this.serverUrl) + '/api/v4/websocket';
if (this.connectingCallback) {
this.connectingCallback();
@@ -105,7 +101,7 @@ export default class WebSocketClient {
this.url = connectionUrl;
const reliableWebSockets = hasReliableWebsocket(version, reliableWebsocketConfig);
const reliableWebSockets = hasReliableWebsocket(config);
if (reliableWebSockets) {
// Add connection id, and last_sequence_number to the query param.
// We cannot also send it as part of the auth_challenge, because the session cookie is already sent with the request.
@@ -133,11 +129,6 @@ export default class WebSocketClient {
headers.Authorization = `Bearer ${this.token}`;
}
const {client} = await getOrCreateWebSocketClient(this.url, {headers, timeoutInterval: WEBSOCKET_TIMEOUT});
// Check again if the client is the same, to avoid race conditions
if (this.conn === client) {
return;
}
this.conn = client;
} catch (error) {
return;

View File

@@ -14,7 +14,7 @@ import TeamList from './team_list';
type Props = {
iconPad?: boolean;
canJoinOtherTeams: boolean;
hasMoreThanOneTeam: boolean;
teamsCount: number;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
@@ -36,8 +36,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
};
});
export default function TeamSidebar({iconPad, canJoinOtherTeams, hasMoreThanOneTeam}: Props) {
const initialWidth = hasMoreThanOneTeam ? TEAM_SIDEBAR_WIDTH : 0;
export default function TeamSidebar({iconPad, canJoinOtherTeams, teamsCount}: Props) {
const initialWidth = teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0;
const width = useSharedValue(initialWidth);
const marginTop = useSharedValue(iconPad ? 44 : 0);
const theme = useTheme();
@@ -58,8 +58,8 @@ export default function TeamSidebar({iconPad, canJoinOtherTeams, hasMoreThanOneT
}, [iconPad]);
useEffect(() => {
width.value = hasMoreThanOneTeam ? TEAM_SIDEBAR_WIDTH : 0;
}, [hasMoreThanOneTeam]);
width.value = teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0;
}, [teamsCount]);
return (
<Animated.View style={[styles.container, transform]}>

View File

@@ -3,7 +3,7 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$, Observable} from 'rxjs';
import {of as of$} from 'rxjs';
import {switchMap, combineLatestWith, distinctUntilChanged} from 'rxjs/operators';
import {Preferences} from '@constants';
@@ -19,7 +19,6 @@ import CategoryBody from './category_body';
import type {WithDatabaseArgs} from '@typings/database/database';
import type CategoryModel from '@typings/database/models/servers/category';
import type ChannelModel from '@typings/database/models/servers/channel';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type PreferenceModel from '@typings/database/models/servers/preference';
type EnhanceProps = {
@@ -31,7 +30,8 @@ type EnhanceProps = {
const withUserId = withObservables([], ({database}: WithDatabaseArgs) => ({currentUserId: observeCurrentUserId(database)}));
const observeCategoryChannels = (category: CategoryModel, myChannels: Observable<MyChannelModel[]>) => {
const observeCategoryChannels = (category: CategoryModel) => {
const myChannels = category.myChannels.observeWithColumns(['last_post_at', 'is_unread']);
const channels = category.channels.observeWithColumns(['create_at', 'display_name']);
const manualSort = category.categoryChannelsBySortOrder.observeWithColumns(['sort_order']);
return myChannels.pipe(
@@ -57,8 +57,7 @@ const observeCategoryChannels = (category: CategoryModel, myChannels: Observable
};
const enhanced = withObservables([], ({category, currentUserId, database, isTablet, locale}: EnhanceProps) => {
const categoryMyChannels = category.myChannels.observeWithColumns(['last_post_at', 'is_unread']);
const channelsWithMyChannel = observeCategoryChannels(category, categoryMyChannels);
const channelsWithMyChannel = observeCategoryChannels(category);
const currentChannelId = isTablet ? observeCurrentChannelId(database) : of$('');
const lastUnreadId = isTablet ? observeLastUnreadChannelId(database) : of$(undefined);
@@ -78,9 +77,9 @@ const enhanced = withObservables([], ({category, currentUserId, database, isTabl
);
}
const notifyPropsPerChannel = categoryMyChannels.pipe(
const notifyPropsPerChannel = channelsWithMyChannel.pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((mc) => observeNotifyPropsByChannels(database, mc)),
switchMap((cwms) => observeNotifyPropsByChannels(database, cwms.map((c) => c.myChannel))),
);
const hiddenDmPrefs = queryPreferencesByCategoryAndName(database, Preferences.CATEGORIES.DIRECT_CHANNEL_SHOW, undefined, 'false').

View File

@@ -4,7 +4,7 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
import {switchMap} from 'rxjs/operators';
import {Permissions} from '@constants';
import {observePermissionForTeam} from '@queries/servers/role';
@@ -25,7 +25,6 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const canJoinChannels = combineLatest([currentUser, team]).pipe(
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.JOIN_PUBLIC_CHANNELS, true)),
distinctUntilChanged(),
);
const canCreatePublicChannels = combineLatest([currentUser, team]).pipe(
@@ -38,7 +37,6 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const canCreateChannels = combineLatest([canCreatePublicChannels, canCreatePrivateChannels]).pipe(
switchMap(([open, priv]) => of$(open || priv)),
distinctUntilChanged(),
);
const canAddUserToTeam = combineLatest([currentUser, team]).pipe(
@@ -50,11 +48,9 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
canJoinChannels,
canInvitePeople: combineLatest([enableOpenServer, canAddUserToTeam]).pipe(
switchMap(([openServer, addUser]) => of$(openServer && addUser)),
distinctUntilChanged(),
),
displayName: team.pipe(
switchMap((t) => of$(t?.displayName)),
distinctUntilChanged(),
),
pushProxyStatus: observePushVerificationStatus(database),
};

View File

@@ -33,8 +33,8 @@ describe('components/categories_list', () => {
it('should render', () => {
const wrapper = renderWithEverything(
<CategoriesList
moreThanOneTeam={false}
hasChannels={true}
teamsCount={1}
channelsCount={1}
/>,
{database},
);
@@ -46,8 +46,8 @@ describe('components/categories_list', () => {
const wrapper = renderWithEverything(
<CategoriesList
isCRTEnabled={true}
moreThanOneTeam={false}
hasChannels={true}
teamsCount={1}
channelsCount={1}
/>,
{database},
);
@@ -67,8 +67,8 @@ describe('components/categories_list', () => {
jest.useFakeTimers();
const wrapper = renderWithEverything(
<CategoriesList
moreThanOneTeam={false}
hasChannels={true}
teamsCount={0}
channelsCount={1}
/>,
{database},
);
@@ -89,8 +89,8 @@ describe('components/categories_list', () => {
jest.useFakeTimers();
const wrapper = renderWithEverything(
<CategoriesList
moreThanOneTeam={true}
hasChannels={false}
teamsCount={1}
channelsCount={0}
/>,
{database},
);

View File

@@ -27,28 +27,28 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
}));
type ChannelListProps = {
hasChannels: boolean;
channelsCount: number;
iconPad?: boolean;
isCRTEnabled?: boolean;
moreThanOneTeam: boolean;
teamsCount: number;
};
const getTabletWidth = (moreThanOneTeam: boolean) => {
return TABLET_SIDEBAR_WIDTH - (moreThanOneTeam ? TEAM_SIDEBAR_WIDTH : 0);
const getTabletWidth = (teamsCount: number) => {
return TABLET_SIDEBAR_WIDTH - (teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0);
};
const CategoriesList = ({hasChannels, iconPad, isCRTEnabled, moreThanOneTeam}: ChannelListProps) => {
const CategoriesList = ({channelsCount, iconPad, isCRTEnabled, teamsCount}: ChannelListProps) => {
const theme = useTheme();
const styles = getStyleSheet(theme);
const {width} = useWindowDimensions();
const isTablet = useIsTablet();
const tabletWidth = useSharedValue(isTablet ? getTabletWidth(moreThanOneTeam) : 0);
const tabletWidth = useSharedValue(isTablet ? getTabletWidth(teamsCount) : 0);
useEffect(() => {
if (isTablet) {
tabletWidth.value = getTabletWidth(moreThanOneTeam);
tabletWidth.value = getTabletWidth(teamsCount);
}
}, [isTablet && moreThanOneTeam]);
}, [isTablet && teamsCount]);
const tabletStyle = useAnimatedStyle(() => {
if (!isTablet) {
@@ -61,7 +61,7 @@ const CategoriesList = ({hasChannels, iconPad, isCRTEnabled, moreThanOneTeam}: C
}, [isTablet, width]);
const content = useMemo(() => {
if (!hasChannels) {
if (channelsCount < 1) {
return (<LoadChannelsError/>);
}

View File

@@ -29,10 +29,9 @@ import Servers from './servers';
import type {LaunchType} from '@typings/launch';
type ChannelProps = {
hasChannels: boolean;
channelsCount: number;
isCRTEnabled: boolean;
hasTeams: boolean;
hasMoreThanOneTeam: boolean;
teamsCount: number;
isLicensed: boolean;
showToS: boolean;
launchType: LaunchType;
@@ -127,10 +126,10 @@ const ChannelListScreen = (props: ChannelProps) => {
}, [theme, insets.top]);
useEffect(() => {
if (!props.hasTeams) {
if (!props.teamsCount) {
resetToTeams();
}
}, [Boolean(props.hasTeams)]);
}, [Boolean(props.teamsCount)]);
useEffect(() => {
const back = BackHandler.addEventListener('hardwareBackPress', handleBackPress);
@@ -177,13 +176,13 @@ const ChannelListScreen = (props: ChannelProps) => {
>
<TeamSidebar
iconPad={canAddOtherServers}
hasMoreThanOneTeam={props.hasMoreThanOneTeam}
teamsCount={props.teamsCount}
/>
<CategoriesList
iconPad={canAddOtherServers && !props.hasMoreThanOneTeam}
iconPad={canAddOtherServers && props.teamsCount <= 1}
isCRTEnabled={props.isCRTEnabled}
moreThanOneTeam={props.hasMoreThanOneTeam}
hasChannels={props.hasChannels}
teamsCount={props.teamsCount}
channelsCount={props.channelsCount}
/>
{isTablet &&
<AdditionalTabletView/>

View File

@@ -4,7 +4,7 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
import {switchMap} from 'rxjs/operators';
import {queryAllMyChannelsForTeam} from '@queries/servers/channel';
import {observeCurrentTeamId, observeLicense} from '@queries/servers/system';
@@ -21,22 +21,11 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
switchMap((lcs) => (lcs ? of$(lcs.IsLicensed === 'true') : of$(false))),
);
const teamsCount = queryMyTeams(database).observeCount(false);
return {
isCRTEnabled: observeIsCRTEnabled(database),
hasTeams: teamsCount.pipe(
switchMap((v) => of$(v > 0)),
distinctUntilChanged(),
),
hasMoreThanOneTeam: teamsCount.pipe(
switchMap((v) => of$(v > 1)),
distinctUntilChanged(),
),
hasChannels: observeCurrentTeamId(database).pipe(
teamsCount: queryMyTeams(database).observeCount(false),
channelsCount: observeCurrentTeamId(database).pipe(
switchMap((id) => (id ? queryAllMyChannelsForTeam(database, id).observeCount(false) : of$(0))),
switchMap((v) => of$(v > 0)),
distinctUntilChanged(),
),
isLicensed,
showToS: observeShowToS(database),

View File

@@ -3,7 +3,7 @@
import {General, Preferences} from '@constants';
import {DMS_CATEGORY} from '@constants/categories';
import {getPreferenceAsBool} from '@helpers/api/preference';
import {getPreferenceAsBool, getPreferenceValue} from '@helpers/api/preference';
import {isDMorGM} from '@utils/channel';
import {getUserIdFromChannelName} from '@utils/user';
@@ -42,18 +42,15 @@ export const filterAutoclosedDMs = (
// Only autoclose DMs that haven't been assigned to a category
return channelsWithMyChannel;
}
const prefMap = preferences.reduce((acc, v) => {
const existing = acc.get(v.name);
acc.set(v.name, Math.max((v.value as unknown as number) || 0, existing || 0));
return acc;
}, new Map<string, number>());
const getLastViewedAt = (cwm: ChannelWithMyChannel) => {
// The server only ever sets the last_viewed_at to the time of the last post in channel, so we may need
// to use the preferences added for the previous version of autoclosing DMs.
const id = cwm.channel.id;
return Math.max(
cwm.myChannel.lastViewedAt,
prefMap.get(id) || 0,
getPreferenceValue<number>(preferences, Preferences.CATEGORIES.CHANNEL_APPROXIMATE_VIEW_TIME, id, 0),
getPreferenceValue<number>(preferences, Preferences.CATEGORIES.CHANNEL_OPEN_TIME, id, 0),
);
};
@@ -181,7 +178,7 @@ export const sortChannels = (sorting: CategorySorting, channelsWithMyChannel: Ch
}).map((cwm) => cwm.channel);
} else if (sorting === 'manual') {
return channelsWithMyChannel.sort((cwmA, cwmB) => {
return cwmA.sortOrder - cwmB.sortOrder;
return cwmB.sortOrder - cwmA.sortOrder;
}).map((cwm) => cwm.channel);
}

View File

@@ -3,10 +3,10 @@
import {isMinimumServerVersion} from './helpers';
export function hasReliableWebsocket(version?: string, reliableWebsocketsConfig?: string) {
if (version && isMinimumServerVersion(version, 6, 5)) {
export function hasReliableWebsocket(config: ClientConfig) {
if (isMinimumServerVersion(config.Version, 6, 5)) {
return true;
}
return reliableWebsocketsConfig === 'true';
return config.EnableReliableWebSockets === 'true';
}

View File

@@ -81,6 +81,7 @@ class AccountScreen {
open = async () => {
// # Open account screen
await waitFor(HomeScreen.accountTab).toBeVisible().withTimeout(timeouts.TWO_SEC);
await HomeScreen.accountTab.tap();
return this.toBeVisible();
@@ -92,7 +93,7 @@ class AccountScreen {
await expect(Alert.logoutTitle(serverDisplayName)).toBeVisible();
}
await Alert.logoutButton.tap();
await expect(this.accountScreen).not.toBeVisible();
await waitFor(this.accountScreen).not.toBeVisible().withTimeout(timeouts.TEN_SEC);
};
}

View File

@@ -6,7 +6,7 @@ import {
ProfilePicture,
} from '@support/ui/component';
import {ChannelScreen} from '@support/ui/screen';
import {timeouts, wait} from '@support/utils';
import {isAndroid, timeouts, wait} from '@support/utils';
import {expect} from 'detox';
class ChannelInfoScreen {
@@ -98,6 +98,7 @@ class ChannelInfoScreen {
open = async () => {
// # Open channel info screen
await waitFor(ChannelScreen.headerTitle).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ChannelScreen.headerTitle.tap();
return this.toBeVisible();
@@ -165,6 +166,9 @@ class ChannelInfoScreen {
leaveChannel = async ({confirm = true} = {}) => {
await waitFor(this.leaveChannelOption).toExist().withTimeout(timeouts.TWO_SEC);
if (isAndroid()) {
await this.scrollView.scrollTo('bottom');
}
await this.leaveChannelOption.tap({x: 1, y: 1});
const {
leaveChannelTitle,

View File

@@ -58,6 +58,7 @@ describe('Channels - Archive Channel', () => {
// # Open a public channel screen, open channel info screen, and tap on archive channel option and confirm
const {channel: publicChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'O', teamId: testTeam.id});
await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, publicChannel.id);
await wait(timeouts.TWO_SEC);
await device.reloadReactNative();
await ChannelScreen.open(channelsCategory, publicChannel.name);
await ChannelInfoScreen.open();
@@ -88,6 +89,7 @@ describe('Channels - Archive Channel', () => {
// # Open a public channel screen, open channel info screen, and tap on archive channel option and cancel
const {channel: publicChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'O', teamId: testTeam.id});
await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, publicChannel.id);
await wait(timeouts.TWO_SEC);
await device.reloadReactNative();
await ChannelScreen.open(channelsCategory, publicChannel.name);
await ChannelInfoScreen.open();
@@ -105,6 +107,7 @@ describe('Channels - Archive Channel', () => {
// # Open a private channel screen, open channel info screen, and tap on archive channel option and confirm
const {channel: privateChannel} = await Channel.apiCreateChannel(siteOneUrl, {type: 'P', teamId: testTeam.id});
await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, privateChannel.id);
await wait(timeouts.TWO_SEC);
await device.reloadReactNative();
await ChannelScreen.open(channelsCategory, privateChannel.name);
await ChannelInfoScreen.open();

View File

@@ -64,6 +64,7 @@ describe('Channels - Channel Info', () => {
await expect(ChannelInfoScreen.pinnedMessagesOption).toBeVisible();
await expect(ChannelInfoScreen.copyChannelLinkOption).toBeVisible();
await expect(ChannelInfoScreen.editChannelOption).toBeVisible();
await ChannelInfoScreen.scrollView.scrollTo('bottom');
await expect(ChannelInfoScreen.leaveChannelOption).toBeVisible();
await waitFor(ChannelInfoScreen.archiveChannelOption).toBeVisible().whileElement(by.id(ChannelInfoScreen.testID.scrollView)).scroll(50, 'down');
await expect(ChannelInfoScreen.archiveChannelOption).toBeVisible();

View File

@@ -82,6 +82,7 @@ describe('Channels - Channel List', () => {
// * Verify on first channel
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText(testChannel.display_name);
await expect(ChannelScreen.introDisplayName).toHaveText(testChannel.display_name);
// # Go back to channel list screen and tap on a second channel
await ChannelScreen.back();
@@ -91,15 +92,7 @@ describe('Channels - Channel List', () => {
// * Verify on second channel
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText('Off-Topic');
// # Go back to channel list screen and tap on a third channel
await ChannelScreen.back();
await ChannelListScreen.toBeVisible();
await ChannelListScreen.getChannelItemDisplayName(channelsCategory, townSquareChannelName).tap();
// * Verify on third channel
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText('Town Square');
await expect(ChannelScreen.introDisplayName).toHaveText('Off-Topic');
// # Go back to channel list screen
await ChannelScreen.back();

View File

@@ -23,7 +23,7 @@ import {
PostOptionsScreen,
ServerScreen,
} from '@support/ui/screen';
import {getRandomId} from '@support/utils';
import {getRandomId, isAndroid} from '@support/utils';
import {expect} from 'detox';
describe('Channels - Channel Post List', () => {
@@ -52,6 +52,10 @@ describe('Channels - Channel Post List', () => {
it('MM-T4773_1 - should match elements on channel screen', async () => {
// # Open a channel screen
await ChannelScreen.open('channels', testChannel.name);
if (isAndroid()) {
await ChannelScreen.back();
await ChannelScreen.open('channels', testChannel.name);
}
// * Verify basic elements on channel screen
await expect(ChannelScreen.backButton).toBeVisible();
@@ -77,6 +81,10 @@ describe('Channels - Channel Post List', () => {
// # Open a channel screen and post a message
const message = `Message ${getRandomId()}`;
await ChannelScreen.open('channels', testChannel.name);
if (isAndroid()) {
await ChannelScreen.back();
await ChannelScreen.open('channels', testChannel.name);
}
await ChannelScreen.postMessage(message);
// * Verify message is added to post list

View File

@@ -7,7 +7,7 @@
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
import {serverOneUrl} from '@support/test_config';
import {siteOneUrl} from '@support/test_config';
import {
ChannelScreen,
ChannelListScreen,
@@ -17,21 +17,21 @@ import {
ServerScreen,
ChannelInfoScreen,
} from '@support/ui/screen';
import {getAdminAccount, getRandomId} from '@support/utils';
import {getAdminAccount, getRandomId, timeouts} from '@support/utils';
import {expect} from 'detox';
describe('Channels - Convert to Private Channel', () => {
const serverOneDisplayName = 'Server 1';
const siteOneDisplayName = 'Server 1';
beforeAll(async () => {
// # Log in to server as admin
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
await ServerScreen.connectToServer(siteOneUrl, siteOneDisplayName);
await LoginScreen.login(getAdminAccount());
});
beforeEach(async () => {
// * Verify on channel list screen
await ChannelListScreen.toBeVisible();
await waitFor(ChannelListScreen.channelListScreen).toBeVisible().withTimeout(timeouts.TWO_MIN);
});
afterAll(async () => {

View File

@@ -81,9 +81,10 @@ describe('Channels - Mute and Unmute Channel', () => {
// * Verify channel is muted
await expect(ChannelInfoScreen.unmuteAction).toBeVisible();
await wait(timeouts.FOUR_SEC);
// # Tap on muted action to unmute the channel
await ChannelInfoScreen.unmuteAction.tap();
await ChannelInfoScreen.unmuteAction.longPress();
// * Verify channel is unmuted
await expect(ChannelInfoScreen.muteAction).toBeVisible();

View File

@@ -17,7 +17,7 @@ import {
ServerScreen,
ChannelInfoScreen,
} from '@support/ui/screen';
import {getAdminAccount, getRandomId} from '@support/utils';
import {getAdminAccount, getRandomId, timeouts} from '@support/utils';
import {expect} from 'detox';
describe('Channels - Unarchive Channel', () => {
@@ -32,7 +32,7 @@ describe('Channels - Unarchive Channel', () => {
beforeEach(async () => {
// * Verify on channel list screen
await ChannelListScreen.toBeVisible();
await waitFor(ChannelListScreen.channelListScreen).toBeVisible().withTimeout(timeouts.TWO_MIN);
});
afterAll(async () => {

View File

@@ -23,7 +23,7 @@ import {
PostOptionsScreen,
ServerScreen,
} from '@support/ui/screen';
import {getRandomId} from '@support/utils';
import {getRandomId, timeouts} from '@support/utils';
import {expect} from 'detox';
describe('Messaging - Follow and Unfollow Message', () => {
@@ -67,14 +67,14 @@ describe('Messaging - Follow and Unfollow Message', () => {
// * Verify message is followed by user via post footer
const {postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(post.id, message);
await expect(postListPostItemFooterFollowingButton).toBeVisible();
await waitFor(postListPostItemFooterFollowingButton).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Open post options for message and tap on unfollow message option
await ChannelScreen.openPostOptionsFor(post.id, message);
await PostOptionsScreen.followingThreadOption.tap();
// * Verify message is not followed by user via post footer
await expect(postListPostItemFooterFollowingButton).not.toBeVisible();
await waitFor(postListPostItemFooterFollowingButton).not.toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Go back to channel list screen
await ChannelScreen.back();
@@ -91,13 +91,13 @@ describe('Messaging - Follow and Unfollow Message', () => {
// * Verify message is followed by user via post footer
const {postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(post.id, message);
await expect(postListPostItemFooterFollowingButton).toBeVisible();
await waitFor(postListPostItemFooterFollowingButton).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Tap on following button via post footer
await postListPostItemFooterFollowingButton.tap();
// * Verify message is not followed by user via post footer
await expect(postListPostItemFooterFollowingButton).not.toBeVisible();
await waitFor(postListPostItemFooterFollowingButton).not.toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Go back to channel list screen
await ChannelScreen.back();

View File

@@ -30,7 +30,7 @@ import {
ServerScreen,
ServerListScreen,
} from '@support/ui/screen';
import {timeouts, wait} from '@support/utils';
import {isAndroid, isIos, timeouts, wait} from '@support/utils';
import {expect} from 'detox';
describe('Server Login - Server List', () => {
@@ -98,7 +98,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
// * Verify second server is active and first server is inactive
await waitFor(ServerListScreen.getServerItemActive(serverTwoDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
@@ -118,7 +123,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
// * Verify third server is active, and first and second servers are inactive
await waitFor(ServerListScreen.getServerItemActive(serverThreeDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
@@ -135,7 +145,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen and tap on third server
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemInactive(serverThreeDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ServerListScreen.getServerItemInactive(serverThreeDisplayName).tap();
@@ -145,7 +160,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen and go back to first server
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemInactive(serverOneDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ServerListScreen.getServerItemInactive(serverOneDisplayName).tap();
});
@@ -156,7 +176,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen, swipe left on first server and tap on edit option
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemActive(serverOneDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ServerListScreen.getServerItemActive(serverOneDisplayName).swipe('left');
await ServerListScreen.getServerItemEditOption(serverOneDisplayName).tap();
@@ -197,7 +222,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen, swipe left on first server and tap on remove option
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemActive(serverOneDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ServerListScreen.getServerItemActive(serverOneDisplayName).swipe('left');
await ServerListScreen.getServerItemRemoveOption(serverOneDisplayName).tap();
@@ -209,7 +239,12 @@ describe('Server Login - Server List', () => {
await Alert.removeButton3.tap();
await wait(timeouts.ONE_SEC);
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
// * Verify first server is removed
await expect(ServerListScreen.getServerItemActive(serverOneDisplayName)).not.toExist();
@@ -228,7 +263,12 @@ describe('Server Login - Server List', () => {
// # Open server list screen, swipe left on third server and tap on logout option
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemInactive(serverThreeDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ServerListScreen.getServerItemInactive(serverThreeDisplayName).swipe('left');
await ServerListScreen.getServerItemLogoutOption(serverThreeDisplayName).tap();
@@ -253,12 +293,27 @@ describe('Server Login - Server List', () => {
// # Open server list screen, attempt to add a server already logged in and with inactive session
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
// await ServerListScreen.closeTutorial();
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await ServerListScreen.addServerButton.tap();
await expect(ServerScreen.headerTitleAddServer).toBeVisible();
await ServerScreen.serverUrlInput.replaceText(serverTwoUrl);
if (isAndroid()) {
await ServerScreen.serverUrlInput.tapReturnKey();
}
await ServerScreen.serverDisplayNameInput.replaceText(serverTwoDisplayName);
await ServerScreen.tapConnectButton();
if (isAndroid()) {
await ServerScreen.serverDisplayNameInput.tapReturnKey();
}
if (isIos()) {
await ServerScreen.tapConnectButton();
}
// * Verify same name server error
const sameNameServerError = 'You are using this name for another server.';
@@ -266,8 +321,17 @@ describe('Server Login - Server List', () => {
// # Attempt to add a server already logged in and with active session, with the same server display name
await ServerScreen.serverUrlInput.replaceText(serverOneUrl);
if (isAndroid()) {
await ServerScreen.serverUrlInput.tapReturnKey();
}
await ServerScreen.serverDisplayNameInput.replaceText(serverOneDisplayName);
await ServerScreen.tapConnectButton();
if (isAndroid()) {
await ServerScreen.serverDisplayNameInput.tapReturnKey();
}
if (isIos()) {
await ServerScreen.tapConnectButton();
}
// * Verify same name server error
await expect(ServerScreen.serverDisplayNameInputError).toHaveText(sameNameServerError);
@@ -275,7 +339,12 @@ describe('Server Login - Server List', () => {
// # Close server screen, open server list screen, log out of second server, and go back to first server
await ServerScreen.close();
await ServerListScreen.open();
await ServerListScreen.serverListScreen.swipe('up');
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemInactive(serverTwoDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);
await ServerListScreen.getServerItemInactive(serverTwoDisplayName).swipe('left');
await ServerListScreen.getServerItemLogoutOption(serverTwoDisplayName).tap();

View File

@@ -81,7 +81,6 @@ describe('Smoke Test - Channels', () => {
// * Verify on the other channel screen
await ChannelScreen.toBeVisible();
await expect(ChannelScreen.headerTitle).toHaveText(testChannel.display_name);
await expect(ChannelScreen.introDisplayName).toHaveText(testChannel.display_name);
// # Go back to channel list screen
await ChannelScreen.back();
@@ -189,6 +188,7 @@ describe('Smoke Test - Channels', () => {
// # Open a channel screen, open channel info screen, and tap on archive channel option and confirm
const {channel} = await Channel.apiCreateChannel(siteOneUrl, {teamId: testTeam.id});
await Channel.apiAddUserToChannel(siteOneUrl, testUser.id, channel.id);
await wait(timeouts.TWO_SEC);
await device.reloadReactNative();
await ChannelScreen.open(channelsCategory, channel.name);
await ChannelInfoScreen.open();

View File

@@ -144,7 +144,7 @@ describe('Smoke Test - Messaging', () => {
await element(by.text('🤡')).tap();
// * Verify reaction is added to the message
await expect(element(by.text('🤡').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).toBeVisible();
await waitFor(element(by.text('🤡').withAncestor(by.id(`channel.post_list.post.${post.id}`)))).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Go back to channel list screen
await ChannelScreen.back();
@@ -161,7 +161,7 @@ describe('Smoke Test - Messaging', () => {
// * Verify message is followed by user via post footer
const {postListPostItem, postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(post.id, message);
await expect(postListPostItemFooterFollowingButton).toBeVisible();
await waitFor(postListPostItemFooterFollowingButton).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Tap on following button via post footer
await postListPostItemFooterFollowingButton.tap();

View File

@@ -90,6 +90,7 @@ describe('Smoke Test - Server Login', () => {
if (isIos()) {
await ServerListScreen.serverListTitle.swipe('up');
} else if (isAndroid()) {
await waitFor(ServerListScreen.serverListTitle).toBeVisible().withTimeout(timeouts.TWO_SEC);
await ServerListScreen.serverListTitle.swipe('up', 'fast', 0.1, 0.5, 0.3);
}
await waitFor(ServerListScreen.getServerItemInactive(serverTwoDisplayName)).toBeVisible().withTimeout(timeouts.TEN_SEC);

View File

@@ -131,7 +131,7 @@ describe('Threads - Follow and Unfollow Thread', () => {
// * Verify thread is not followed by user via post footer
const {postListPostItemFooterFollowButton, postListPostItemFooterFollowingButton} = ChannelScreen.getPostListPostItem(parentPost.id, parentMessage);
await expect(postListPostItemFooterFollowButton).toBeVisible();
await waitFor(postListPostItemFooterFollowButton).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Open post options for thread
await ChannelScreen.openPostOptionsFor(parentPost.id, parentMessage);
@@ -143,13 +143,13 @@ describe('Threads - Follow and Unfollow Thread', () => {
await PostOptionsScreen.followThreadOption.tap();
// * Verify thread is followed by user via post footer
await expect(postListPostItemFooterFollowingButton).toBeVisible();
await waitFor(postListPostItemFooterFollowingButton).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Open post options for thread
await ChannelScreen.openPostOptionsFor(parentPost.id, parentMessage);
// * Verify thread is followed by user via post options
await expect(PostOptionsScreen.followingThreadOption).toBeVisible();
await waitFor(PostOptionsScreen.followingThreadOption).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Go back to channel list screen
await PostOptionsScreen.close();
@@ -177,7 +177,7 @@ describe('Threads - Follow and Unfollow Thread', () => {
await GlobalThreadsScreen.openThreadOptionsFor(parentPost.id);
// * Verify thread is followed by user via thread options
await expect(ThreadOptionsScreen.followingThreadOption).toBeVisible();
await waitFor(ThreadOptionsScreen.followingThreadOption).toBeVisible().withTimeout(timeouts.TWO_SEC);
// # Tap on unfollow thread option
await ThreadOptionsScreen.followingThreadOption.tap();

View File

@@ -1,23 +1,23 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.6)
CFPropertyList (3.0.5)
rexml
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.721.0)
aws-sdk-core (3.170.0)
aws-partitions (1.695.0)
aws-sdk-core (3.169.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.63.0)
aws-sdk-kms (1.62.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.119.1)
aws-sdk-s3 (1.118.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
@@ -36,7 +36,7 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.99.0)
excon (0.97.1)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -66,7 +66,7 @@ GEM
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.212.1)
fastlane (2.211.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -109,11 +109,11 @@ GEM
fastlane-plugin-android_change_string_app_name (0.1.1)
nokogiri
fastlane-plugin-find_replace_string (0.1.0)
fastlane-plugin-versioning_android (0.1.1)
fastlane-plugin-versioning_android (0.1.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.35.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.0)
google-apis-androidpublisher_v3 (0.32.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-core (0.9.5)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -122,10 +122,10 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.17.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-iamcredentials_v1 (0.16.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-playcustomapp_v1 (0.12.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.9.0, < 2.a)
google-cloud-core (1.6.0)
@@ -133,7 +133,7 @@ GEM
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.1)
google-cloud-errors (1.3.0)
google-cloud-storage (1.44.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
@@ -155,7 +155,7 @@ GEM
httpclient (2.8.3)
jmespath (1.6.2)
json (2.6.3)
jwt (2.7.0)
jwt (2.6.0)
memoist (0.16.2)
mini_magick (4.12.0)
mini_mime (1.1.2)
@@ -164,12 +164,12 @@ GEM
multipart-post (2.0.0)
nanaimo (0.3.0)
naturally (2.2.1)
nokogiri (1.14.2)
nokogiri (1.14.0)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
optparse (0.1.1)
os (1.1.4)
plist (3.7.0)
plist (3.6.0)
public_suffix (5.0.1)
racc (1.6.2)
rake (13.0.6)
@@ -188,7 +188,7 @@ GEM
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.10)
simctl (1.6.8)
CFPropertyList
naturally
slack-notifier (2.3.2)
@@ -205,7 +205,7 @@ GEM
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.8.1)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)

View File

@@ -1128,7 +1128,7 @@
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 461;
CURRENT_PROJECT_VERSION = 460;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@@ -1172,7 +1172,7 @@
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 461;
CURRENT_PROJECT_VERSION = 460;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@@ -1315,7 +1315,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 461;
CURRENT_PROJECT_VERSION = 460;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
GCC_C_LANGUAGE_STANDARD = gnu11;
@@ -1366,7 +1366,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 461;
CURRENT_PROJECT_VERSION = 460;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
GCC_C_LANGUAGE_STANDARD = gnu11;

View File

@@ -37,7 +37,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>461</string>
<string>460</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>

View File

@@ -21,7 +21,7 @@
<key>CFBundleShortVersionString</key>
<string>2.1.0</string>
<key>CFBundleVersion</key>
<string>461</string>
<string>460</string>
<key>UIAppFonts</key>
<array>
<string>OpenSans-Bold.ttf</string>

View File

@@ -21,7 +21,7 @@
<key>CFBundleShortVersionString</key>
<string>2.1.0</string>
<key>CFBundleVersion</key>
<string>461</string>
<string>460</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>

14
package-lock.json generated
View File

@@ -19,7 +19,7 @@
"@gorhom/bottom-sheet": "4.4.5",
"@mattermost/compass-icons": "0.1.35",
"@mattermost/react-native-emm": "1.3.5",
"@mattermost/react-native-network-client": "1.3.2",
"@mattermost/react-native-network-client": "1.3.1",
"@mattermost/react-native-paste-input": "0.6.2",
"@mattermost/react-native-turbo-log": "0.2.3",
"@mattermost/react-native-turbo-mailer": "0.2.4",
@@ -3241,9 +3241,9 @@
}
},
"node_modules/@mattermost/react-native-network-client": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.2.tgz",
"integrity": "sha512-3GFNzMXZWlIXXDYQLIJlKRf+HUZKP0F7mpZ1rSTgoTmUeFdqde4uRiU/L96COg34rAdeFRFrgpk0DxEnT7NiVg==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.1.tgz",
"integrity": "sha512-DtwVLV/NUE6MkXOlVZG+4QJXou6nHMdmsxnP1+RqhOeSw5jJlQvxmQgxzxvxLpaWOag+wgB1zpDulGNbr/Cz6Q==",
"dependencies": {
"validator": "13.9.0",
"zod": "3.20.6"
@@ -24297,9 +24297,9 @@
"requires": {}
},
"@mattermost/react-native-network-client": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.2.tgz",
"integrity": "sha512-3GFNzMXZWlIXXDYQLIJlKRf+HUZKP0F7mpZ1rSTgoTmUeFdqde4uRiU/L96COg34rAdeFRFrgpk0DxEnT7NiVg==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.1.tgz",
"integrity": "sha512-DtwVLV/NUE6MkXOlVZG+4QJXou6nHMdmsxnP1+RqhOeSw5jJlQvxmQgxzxvxLpaWOag+wgB1zpDulGNbr/Cz6Q==",
"requires": {
"validator": "13.9.0",
"zod": "3.20.6"

View File

@@ -16,7 +16,7 @@
"@gorhom/bottom-sheet": "4.4.5",
"@mattermost/compass-icons": "0.1.35",
"@mattermost/react-native-emm": "1.3.5",
"@mattermost/react-native-network-client": "1.3.2",
"@mattermost/react-native-network-client": "1.3.1",
"@mattermost/react-native-paste-input": "0.6.2",
"@mattermost/react-native-turbo-log": "0.2.3",
"@mattermost/react-native-turbo-mailer": "0.2.4",