Move spaces tests from Puppeteer to Cypress (#8645)
* Move spaces tests from Puppeteer to Cypress * Add missing fixture * Tweak synapsedocker to not double error on a docker failure * Fix space hierarchy loading race condition Fixes https://github.com/matrix-org/element-web-rageshakes/issues/10345 * Fix race condition when creating public space with url update code * Try Electron once more due to perms issues around clipboard * Try set browser permissions properly * Try to enable clipboard another way * Try electron again * Try electron again again * Switch to built-in cypress feature for file uploads * Mock clipboard instead * TMPDIR ftw? * uid:gid pls * Clipboard tests can now run on any browser due to mocking * Test Enter as well as button for space creation * Make the test actually work * Update cypress/support/util.ts Co-authored-by: Eric Eastwood <erice@element.io> Co-authored-by: Eric Eastwood <erice@element.io>
This commit is contained in:
parent
d75e2f19c5
commit
f3f14afbbf
21 changed files with 492 additions and 148 deletions
|
@ -18,6 +18,7 @@ import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/client";
|
|||
import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
|
||||
import { IRoomTimelineData } from "matrix-js-sdk/src/models/event-timeline-set";
|
||||
import { RoomState, RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
|
||||
import dis from "../dispatcher/dispatcher";
|
||||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
|
@ -175,6 +176,21 @@ export interface IRoomTimelineActionPayload extends Pick<ActionPayload, "action"
|
|||
isLiveUnfilteredRoomTimelineEvent: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef IRoomStateEventsActionPayload
|
||||
* @type {Object}
|
||||
* @property {string} action 'MatrixActions.RoomState.events'.
|
||||
* @property {MatrixEvent} event the state event received
|
||||
* @property {RoomState} state the room state into which the event was applied
|
||||
* @property {MatrixEvent | null} lastStateEvent the previous value for this (event-type, state-key) tuple in room state
|
||||
*/
|
||||
export interface IRoomStateEventsActionPayload extends Pick<ActionPayload, "action"> {
|
||||
action: 'MatrixActions.RoomState.events';
|
||||
event: MatrixEvent;
|
||||
state: RoomState;
|
||||
lastStateEvent: MatrixEvent | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MatrixActions.Room.timeline action that represents a
|
||||
* MatrixClient `Room.timeline` matrix event, emitted when an event
|
||||
|
@ -210,6 +226,31 @@ function createRoomTimelineAction(
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MatrixActions.Room.timeline action that represents a
|
||||
* MatrixClient `Room.timeline` matrix event, emitted when an event
|
||||
* is added to or removed from a timeline of a room.
|
||||
*
|
||||
* @param {MatrixClient} matrixClient the matrix client.
|
||||
* @param {MatrixEvent} event the state event received
|
||||
* @param {RoomState} state the room state into which the event was applied
|
||||
* @param {MatrixEvent | null} lastStateEvent the previous value for this (event-type, state-key) tuple in room state
|
||||
* @returns {IRoomStateEventsActionPayload} an action of type `MatrixActions.RoomState.events`.
|
||||
*/
|
||||
function createRoomStateEventsAction(
|
||||
matrixClient: MatrixClient,
|
||||
event: MatrixEvent,
|
||||
state: RoomState,
|
||||
lastStateEvent: MatrixEvent | null,
|
||||
): IRoomStateEventsActionPayload {
|
||||
return {
|
||||
action: 'MatrixActions.RoomState.events',
|
||||
event,
|
||||
state,
|
||||
lastStateEvent,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef RoomMembershipAction
|
||||
* @type {Object}
|
||||
|
@ -312,6 +353,7 @@ export default {
|
|||
addMatrixClientListener(matrixClient, RoomEvent.Timeline, createRoomTimelineAction);
|
||||
addMatrixClientListener(matrixClient, RoomEvent.MyMembership, createSelfMembershipAction);
|
||||
addMatrixClientListener(matrixClient, MatrixEventEvent.Decrypted, createEventDecryptedAction);
|
||||
addMatrixClientListener(matrixClient, RoomStateEvent.Events, createRoomStateEventsAction);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -131,6 +131,7 @@ import { IConfigOptions } from "../../IConfigOptions";
|
|||
import { SnakedObject } from "../../utils/SnakedObject";
|
||||
import { leaveRoomBehaviour } from "../../utils/leave-behaviour";
|
||||
import VideoChannelStore from "../../stores/VideoChannelStore";
|
||||
import { IRoomStateEventsActionPayload } from "../../actions/MatrixActionCreators";
|
||||
|
||||
// legacy export
|
||||
export { default as Views } from "../../Views";
|
||||
|
@ -651,6 +652,20 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
case 'view_user_info':
|
||||
this.viewUser(payload.userId, payload.subAction);
|
||||
break;
|
||||
case "MatrixActions.RoomState.events": {
|
||||
const event = (payload as IRoomStateEventsActionPayload).event;
|
||||
if (event.getType() === EventType.RoomCanonicalAlias &&
|
||||
event.getRoomId() === this.state.currentRoomId
|
||||
) {
|
||||
// re-view the current room so we can update alias/id in the URL properly
|
||||
this.viewRoom({
|
||||
action: Action.ViewRoom,
|
||||
room_id: this.state.currentRoomId,
|
||||
metricsTrigger: undefined, // room doesn't change
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Action.ViewRoom: {
|
||||
// Takes either a room ID or room alias: if switching to a room the client is already
|
||||
// known to be in (eg. user clicks on a room in the recents panel), supply the ID
|
||||
|
@ -891,9 +906,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
|
||||
// Store this as the ID of the last room accessed. This is so that we can
|
||||
// persist which room is being stored across refreshes and browser quits.
|
||||
if (localStorage) {
|
||||
localStorage.setItem('mx_last_room_id', room.roomId);
|
||||
}
|
||||
localStorage?.setItem('mx_last_room_id', room.roomId);
|
||||
}
|
||||
|
||||
// If we are redirecting to a Room Alias and it is for the room we already showing then replace history item
|
||||
|
|
|
@ -1137,15 +1137,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
if (!this.state.room || this.state.room.roomId !== state.roomId) return;
|
||||
|
||||
switch (ev.getType()) {
|
||||
case EventType.RoomCanonicalAlias:
|
||||
// re-view the room so MatrixChat can manage the alias in the URL properly
|
||||
dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: this.state.room.roomId,
|
||||
metricsTrigger: undefined, // room doesn't change
|
||||
});
|
||||
break;
|
||||
|
||||
case EventType.RoomTombstone:
|
||||
this.setState({ tombstone: this.getRoomTombstone() });
|
||||
break;
|
||||
|
|
|
@ -524,8 +524,13 @@ export const useRoomHierarchy = (space: Room): {
|
|||
setRooms(hierarchy.rooms);
|
||||
}, [error, hierarchy]);
|
||||
|
||||
const loading = hierarchy?.loading ?? true;
|
||||
return { loading, rooms, hierarchy, loadMore, error };
|
||||
return {
|
||||
loading: hierarchy?.loading ?? true,
|
||||
rooms,
|
||||
hierarchy: hierarchy?.root === space ? hierarchy : undefined,
|
||||
loadMore,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
const useIntersectionObserver = (callback: () => void) => {
|
||||
|
|
|
@ -60,7 +60,7 @@ import {
|
|||
defaultDmsRenderer,
|
||||
defaultRoomsRenderer,
|
||||
} from "../views/dialogs/AddExistingToSpaceDialog";
|
||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
|
||||
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
||||
import ErrorBoundary from "../views/elements/ErrorBoundary";
|
||||
import Field from "../views/elements/Field";
|
||||
|
@ -295,7 +295,7 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
|
|||
/>;
|
||||
});
|
||||
|
||||
const onNextClick = async (ev) => {
|
||||
const onNextClick = async (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
if (busy) return;
|
||||
setError("");
|
||||
|
@ -326,7 +326,7 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
|
|||
setBusy(false);
|
||||
};
|
||||
|
||||
let onClick = (ev) => {
|
||||
let onClick = (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
onFinished();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue