Fix some more cypress tests

This commit is contained in:
Ramon Wenger 2022-10-26 15:47:19 +02:00
parent a0fd6fddd1
commit da6bab1789
11 changed files with 462 additions and 464 deletions

View File

@ -27,6 +27,7 @@ describe('The Room Page (Teacher)', () => {
AddRoomEntry: {
addRoomEntry: {
roomEntry: {
slug: 'entry-slug',
title: entryTitle,
contents: [
{

View File

@ -1,8 +1,13 @@
<template>
<div class="content-form-section">
<h2 class="content-form-section__heading">
<component class="content-form-section__icon" :is="icon" />
<span class="content-form-section__title" data-cy="content-form-section-title">{{ title }}</span>
<component
class="content-form-section__icon"
:is="icon"
/> <span
class="content-form-section__title"
data-cy="content-form-section-title"
>{{ title }}</span>
</h2>
<content-element-actions
@ -22,73 +27,74 @@
</template>
<script lang="ts">
import formElementIcons from '@/components/ui/form-element-icons.js';
import ContentElementActions from '@/components/content-block-form/ContentElementActions.vue';
import { ActionOptions } from '@/@types';
import {defineComponent} from "vue";
import formElementIcons from '@/components/ui/form-element-icons.js';
import ContentElementActions from '@/components/content-block-form/ContentElementActions.vue';
import {ActionOptions} from "@/@types";
export default {
props: {
title: {
type: String,
default: '',
export default defineComponent({
props: {
title: {
type: String,
default: ''
},
icon: {
type: String,
default: ''
},
actions: {
type: Object as () => ActionOptions,
default: () => {}
}
},
icon: {
type: String,
default: '',
},
actions: {
type: Object as () => ActionOptions,
default: () => {},
},
},
components: {
ContentElementActions,
...formElementIcons,
},
};
components: {
ContentElementActions,
...formElementIcons
}
});
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import '~styles/helpers';
.content-form-section {
@include default-box-shadow;
border-radius: $default-border-radius;
padding: $small-spacing $medium-spacing;
margin-bottom: $medium-spacing;
.content-form-section {
@include default-box-shadow;
border-radius: $default-border-radius;
padding: $small-spacing $medium-spacing;
margin-bottom: $medium-spacing;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
grid-template-areas: 'h a' 'c c';
align-items: center;
grid-row-gap: $medium-spacing;
&__heading {
display: flex;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
grid-template-areas: 'h a' 'c c';
align-items: center;
grid-area: h;
margin-bottom: 0;
}
grid-row-gap: $medium-spacing;
&__actions {
grid-area: a;
justify-self: end;
}
&__heading {
display: flex;
align-items: center;
grid-area: h;
margin-bottom: 0;
}
&__title {
@include heading-3;
margin-bottom: 0;
}
&__actions {
grid-area: a;
justify-self: end;
}
&__icon {
width: 28px;
height: 28px;
margin-right: $small-spacing;
}
&__title {
@include heading-3;
margin-bottom: 0;
}
&__content {
grid-area: c;
&__icon {
width: 28px;
height: 28px;
margin-right: $small-spacing;
}
&__content {
grid-area: c;
}
}
}
</style>

View File

@ -1,31 +1,20 @@
<template>
<div class="tip-tap">
<editor-content class="tip-tap__editor-wrapper" :editor="editor" />
<editor-content
class="tip-tap__editor-wrapper"
:editor="editor"
/>
<toggle :bordered="false" :checked="isList" label="Als Liste formatieren" @input="toggleList" />
<toggle
:bordered="false"
:checked="isList"
label="Als Liste formatieren"
@input="toggleList"
/>
</div>
</template>
<script lang="ts">
<<<<<<< HEAD
import Vue, { PropType } from 'vue';
import { Editor, EditorContent } from '@tiptap/vue-2';
import Document from '@tiptap/extension-document';
import Paragraph from '@tiptap/extension-paragraph';
import Text from '@tiptap/extension-text';
import BulletList from '@tiptap/extension-bullet-list';
import ListItem from '@tiptap/extension-list-item';
import Toggle from '@/components/ui/Toggle.vue';
||||||| parent of a423cfde (Apply code changes from migration guide for Vue 3)
import Vue, {PropType} from 'vue';
import {Editor, EditorContent} from "@tiptap/vue-2";
import Document from '@tiptap/extension-document';
import Paragraph from '@tiptap/extension-paragraph';
import Text from '@tiptap/extension-text';
import BulletList from '@tiptap/extension-bullet-list';
import ListItem from '@tiptap/extension-list-item';
import Toggle from "@/components/ui/Toggle.vue";
=======
import {PropType, defineComponent} from 'vue';
import {Editor, EditorContent} from "@tiptap/vue-3";
import Document from '@tiptap/extension-document';
@ -34,143 +23,125 @@ import Toggle from '@/components/ui/Toggle.vue';
import BulletList from '@tiptap/extension-bullet-list';
import ListItem from '@tiptap/extension-list-item';
import Toggle from "@/components/ui/Toggle.vue";
>>>>>>> a423cfde (Apply code changes from migration guide for Vue 3)
interface Data {
editor: Editor | undefined;
}
interface Value {
text: string;
}
interface Data {
editor: Editor | undefined;
}
interface Value {
text: string;
}
<<<<<<< HEAD
export default Vue.extend({
props: {
value: {
type: Object as PropType<Value>,
validator(value: Value) {
return Object.prototype.hasOwnProperty.call(value, 'text');
},
},
},
components: {
Toggle,
EditorContent,
},
data(): Data {
return {
editor: undefined,
};
},
computed: {
isList(): boolean {
return this.editor?.isActive('bulletList') || false;
},
text(): string {
return this.value.text;
},
},
watch: {
value({ text }: Value) {
const editor = this.editor as Editor; // editor is always initialized on mount, cast it
const isSame = editor.getHTML() === text;
if (isSame) {
return;
}
editor.commands.setContent(text, false);
},
},
mounted() {
this.editor = new Editor({
editorProps: {
attributes: {
class: 'tip-tap__editor',
||||||| parent of a423cfde (Apply code changes from migration guide for Vue 3)
export default Vue.extend({
props: {
value: {
type: Object as PropType<Value>,
validator(value: Value) {
return Object.prototype.hasOwnProperty.call(value, 'text');
=======
export default defineComponent({
props: {
value: {
type: Object as PropType<Value>,
validator: (value: Value) => {
return Object.prototype.hasOwnProperty.call(value, 'text');
>>>>>>> a423cfde (Apply code changes from migration guide for Vue 3)
},
},
content: this.text,
extensions: [Document, Paragraph, Text, BulletList, ListItem],
onUpdate: () => {
const text = (this.editor as Editor).getHTML();
this.$emit('input', text);
this.$emit('change-text', text);
},
components: {
Toggle,
EditorContent
},
data(): Data {
return {
editor: undefined,
};
},
computed: {
isList(): boolean {
return this.editor?.isActive('bulletList') || false;
},
<<<<<<< HEAD
});
},
beforeDestroy() {
this.editor?.destroy();
},
methods: {
toggleList() {
const editor = this.editor as Editor;
editor.chain().selectAll().toggleBulletList().run();
||||||| parent of a423cfde (Apply code changes from migration guide for Vue 3)
text(): string {
return this.value.text;
}
=======
text(): string {
return this.value?.text || '';
}
>>>>>>> a423cfde (Apply code changes from migration guide for Vue 3)
},
},
});
watch: {
value({text}: Value) {
const editor = this.editor as Editor; // editor is always initialized on mount, cast it
const isSame = editor.getHTML() === text;
if (isSame) {
return;
}
editor.commands.setContent(text, false);
}
},
mounted() {
this.editor = new Editor({
editorProps: {
attributes: {
class: 'tip-tap__editor'
}
},
content: this.text,
extensions: [
Document,
Paragraph,
Text,
BulletList,
ListItem
],
onUpdate: () => {
const text=(this.editor as Editor).getHTML();
this.$emit('input', text);
this.$emit('change-text', text);
}
});
},
beforeUnmount() {
this.editor?.destroy();
},
methods: {
toggleList() {
const editor = this.editor as Editor;
editor.chain().selectAll().toggleBulletList().run();
},
}
});
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import '~styles/helpers';
.tip-tap {
&__editor-wrapper {
margin-bottom: $medium-spacing;
}
:deep(.tip-tap__editor) {
@include inputstyle;
flex-direction: column;
min-height: 150px;
}
.tip-tap {
:deep(ul) {
padding-left: $medium-spacing;
list-style: initial;
}
&__editor-wrapper {
margin-bottom: $medium-spacing;
}
:deep(li) {
@include inputfont;
}
/deep/ &__editor {
@include inputstyle;
flex-direction: column;
min-height: 150px;
}
:deep(div) {
@include inputfont;
}
/deep/ ul {
padding-left: $medium-spacing;
list-style: initial;
}
:deep(p) {
@include inputfont;
/deep/ li {
@include inputfont;
}
/deep/ div {
@include inputfont;
}
/deep/ p {
@include inputfont;
}
}
}
</style>

View File

@ -4,6 +4,7 @@
class="filter-entry"
data-cy="filter-entry"
:style="categoryStyle"
@click="$emit('filter')"
>
<span class="filter-entry__text">{{ text }}</span>
<span
@ -48,6 +49,8 @@
ChevronRight,
},
emits: ['filter'],
apollo: {
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY,

View File

@ -7,7 +7,7 @@
:category="category"
:is-category="true"
:id="category.id"
@click="setCategoryFilter(category.id)"
@filter="setCategoryFilter(category.id)"
/>
<div class="filter-group__children">
<filter-entry
@ -17,83 +17,84 @@
v-for="type in types"
:id="type.id"
:key="type.id"
@click="setFilter(`type:${type.id}`)"
@filter="setFilter(`type:${type.id}`)"
/>
</div>
</div>
</template>
<script>
import FilterEntry from '@/components/instruments/FilterEntry';
import {defineComponent} from 'vue';
import FilterEntry from '@/components/instruments/FilterEntry';
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
export default {
props: {
title: {
type: String,
default: '',
},
types: {
type: Array,
default: () => [],
},
category: {
type: Object,
default: () => ({}),
},
},
components: {
FilterEntry,
},
apollo: {
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY,
},
},
data() {
return {
instrumentFilter: {
currentFilter: '',
export default defineComponent({
props: {
title: {
type: String,
default: '',
},
};
},
inheritAttrs: false,
types: {
type: Array,
default: () => [],
},
category: {
type: Object,
default: () => ({}),
},
},
components: {
FilterEntry,
},
methods: {
setCategoryFilter(category) {
if (category) {
this.setFilter(`category:${category}`);
} else {
this.setFilter(``);
apollo: {
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY
}
},
setFilter(filter) {
this.$apollo.mutate({
mutation: SET_FILTER_MUTATION,
variables: {
filter,
},
});
},
data() {
return {
instrumentFilter: {
currentFilter: ''
}
};
},
};
inheritAttrs: false,
methods: {
setCategoryFilter(category) {
if (category) {
this.setFilter(`category:${category}`);
} else {
this.setFilter(``);
}
},
setFilter(filter) {
this.$apollo.mutate({
mutation: SET_FILTER_MUTATION,
variables: {
filter
}
});
}
},
});
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import '~styles/helpers';
.filter-group {
border-bottom: 1px solid $color-silver;
padding: $medium-spacing 0;
display: flex;
flex-direction: column;
.filter-group {
border-bottom: 1px solid $color-silver;
padding: $medium-spacing 0;
display: flex;
flex-direction: column;
&__children {
padding-left: $medium-spacing;
&__children {
padding-left: $medium-spacing;
}
}
}
</style>

View File

@ -1,5 +1,8 @@
<template>
<a class="share-icon">
<a
class="share-icon"
@click="$emit('share')"
>
<share-icon class="share-icon__icon" />
<span class="share-icon__text">
<template v-if="!final">Mit Lehrperson teilen</template>
@ -19,6 +22,7 @@
default: false,
},
},
emits: ['share'],
components: {ShareIcon},
};
</script>

View File

@ -1,99 +1,107 @@
<template>
<page-form class="room-form" title="Neuer Raum" @save="$emit('save', localRoom)">
<page-form-input label="Titel" v-model="localRoom.title" />
<page-form
class="room-form"
title="Neuer Raum"
@save="$emit('save', localRoom)"
>
<page-form-input
label="Titel"
v-model="localRoom.title"
/>
<page-form-input label="Beschreibung" type="textarea" v-model="localRoom.description" />
<page-form-input
label="Beschreibung"
type="textarea"
v-model="localRoom.description"
/>
<h2 class="room-form__property-heading">Farbe</h2>
<color-chooser :selected-color="localRoom.appearance" @input="updateColor" />
<h2 class="room-form__property-heading">
Farbe
</h2>
<color-chooser
:selected-color="localRoom.appearance"
@input="updateColor"
/>
<template #footer>
<button type="submit" data-cy="room-form-save" class="button button--primary room-form__save-button">
<button
type="submit"
data-cy="room-form-save"
class="button button--primary room-form__save-button"
>
Speichern
</button>
<<<<<<< HEAD
<router-link to="/rooms" tag="button" class="button"> Abbrechen </router-link>
||||||| parent of c96f9b5b (Remove obsolete tag attributes)
<router-link
to="/rooms"
tag="button"
class="button"
>
Abbrechen
</router-link>
=======
<router-link
to="/rooms"
class="button"
>
Abbrechen
</router-link>
>>>>>>> c96f9b5b (Remove obsolete tag attributes)
</template>
</page-form>
</template>
<script>
import ColorChooser from '@/components/ColorChooser';
import PageForm from '@/components/page-form/PageForm';
import PageFormInput from '@/components/page-form/PageFormInput';
import ColorChooser from '@/components/ColorChooser';
import PageForm from '@/components/page-form/PageForm';
import PageFormInput from '@/components/page-form/PageFormInput';
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
export default {
props: ['room'],
export default {
props: ['room'],
components: {
ColorChooser,
PageForm,
PageFormInput,
},
data() {
return {
localRoom: Object.assign({}, this.room),
me: {},
};
},
created() {
this.$store.dispatch('setSpecialContainerClass', this.localRoom.appearance);
},
beforeDestroy() {
this.$store.dispatch('setSpecialContainerClass', '');
},
methods: {
updateColor(newColor) {
this.localRoom.appearance = newColor;
this.$store.dispatch('setSpecialContainerClass', newColor);
components: {
ColorChooser,
PageForm,
PageFormInput
},
},
apollo: {
me: {
query: ME_QUERY,
data() {
return {
localRoom: Object.assign({}, this.room),
me: {}
};
},
},
};
created() {
this.$store.dispatch('setSpecialContainerClass', this.localRoom.appearance);
},
beforeUnmount() {
this.$store.dispatch('setSpecialContainerClass', '');
},
methods: {
updateColor(newColor) {
this.localRoom.appearance = newColor;
this.$store.dispatch('setSpecialContainerClass', newColor);
}
},
apollo: {
me: {
query: ME_QUERY,
}
},
};
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import "~styles/helpers";
.room-form {
&__property-heading {
@include page-form-input-heading;
}
.room-form {
&__property-heading {
@include page-form-input-heading;
}
&__input,
&__textarea {
width: 100%;
margin-bottom: 35px;
}
&__input,
&__textarea {
width: 100%;
margin-bottom: 35px;
}
&__save-button {
margin-right: 15px;
&__save-button {
margin-right: 15px;
}
}
}
</style>

View File

@ -13,7 +13,7 @@ export default {
RoomActions,
},
beforeDestroy() {
beforeUnmount() {
this.$store.dispatch('setSpecialContainerClass', '');
},

View File

@ -8,7 +8,7 @@
:final="project.final"
data-cy="project-share-link"
class="project__share"
@click="updateProjectShareState(project.slug, !project.final)"
@share="updateProjectShareState(project.slug, !project.final)"
/>
<project-actions :share-buttons="false" class="project__more" :slug="project.slug" v-if="canEdit" />

View File

@ -1,109 +1,110 @@
<template>
<content-block-form :content-block="roomEntry" :features="features" v-if="roomEntry.id" @save="save" @back="goBack" />
<content-block-form
:content-block="roomEntry"
:features="features"
v-if="roomEntry.id"
@save="save"
@back="goBack"
/>
</template>
<script>
import Vue from 'vue';
import {defineComponent} from 'vue';
import ROOM_ENTRY_QUERY from 'gql/queries/roomEntryQuery.gql';
import ROOM_ENTRY_FRAGMENT from 'gql/fragments/roomEntryParts.gql';
import UPDATE_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/updateRoomEntry.gql';
import ROOM_ENTRY_QUERY from 'gql/queries/roomEntryQuery.gql';
import ROOM_ENTRY_FRAGMENT from 'gql/fragments/roomEntryParts.gql';
import UPDATE_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/updateRoomEntry.gql';
import ContentBlockForm from '@/components/content-block-form/ContentBlockForm';
import { ROOMS_FEATURE_SET } from '@/consts/features.consts';
import { ROOM_PAGE } from '@/router/room.names';
import ContentBlockForm from '@/components/content-block-form/ContentBlockForm';
import {ROOMS_FEATURE_SET} from '@/consts/features.consts';
import {ROOM_PAGE} from '@/router/room.names';
export default Vue.extend({
props: {
slug: {
type: String,
required: true,
},
entrySlug: {
type: String,
required: true,
},
},
components: {
ContentBlockForm,
},
data() {
return {
features: ROOMS_FEATURE_SET,
roomEntry: {
title: '',
contents: [],
},
};
},
apollo: {
roomEntry: {
query: ROOM_ENTRY_QUERY,
variables() {
return {
slug: this.entrySlug,
};
export default defineComponent( {
props: {
slug: {
type: String,
required: true
},
entrySlug: {
type: String,
required: true
}
},
},
methods: {
goBack() {
this.$router.push({
name: ROOM_PAGE,
params: {
slug: this.slug,
components: {
ContentBlockForm,
},
data() {
return {
features: ROOMS_FEATURE_SET,
roomEntry: {
title: '',
contents: [],
},
});
},
save({ title, contents }) {
const entry = {
slug: this.roomEntry.slug,
title,
contents,
};
this.$apollo
.mutate({
},
apollo: {
roomEntry: {
query: ROOM_ENTRY_QUERY,
variables() {
return {
slug: this.entrySlug
};
}
}
},
methods: {
goBack() {
this.$router.push({
name: ROOM_PAGE,
params: {
slug: this.slug
}
});
},
save({title, contents}) {
const entry = {
slug: this.roomEntry.slug,
title,
contents,
};
this.$apollo.mutate({
mutation: UPDATE_ROOM_ENTRY_MUTATION,
variables: {
input: {
roomEntry: entry,
},
},
update: (
store,
{
data: {
updateRoomEntry: { roomEntry },
},
}
) => {
},
update: (store, {data: {updateRoomEntry: {roomEntry}}}) => {
try {
const fragment = ROOM_ENTRY_FRAGMENT;
const id = store.identify(roomEntry);
const cachedEntry = store.readQuery({ fragment, id });
const cachedEntry = store.readQuery({fragment, id});
const data = Object.assign({}, cachedEntry, roomEntry);
store.writeFragment({
id,
fragment,
data,
data
});
} catch (e) {
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
}
},
})
.then(() => {
}
}).then(() => {
this.goBack();
});
}
},
},
});
} );
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import '~styles/helpers';
</style>

View File

@ -1,104 +1,107 @@
<template>
<content-block-form :content-block="roomEntry" :features="features" @save="save" @back="goBack" />
<content-block-form
:content-block="roomEntry"
:features="features"
@save="save"
@back="goBack"
/>
</template>
<script>
import Vue from 'vue';
import {defineComponent} from 'vue';
import NEW_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/addRoomEntry.gql';
import ROOM_ENTRIES_QUERY from '@/graphql/gql/queries/roomEntriesQuery.gql';
import NEW_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/addRoomEntry.gql';
import ROOM_ENTRIES_QUERY from '@/graphql/gql/queries/roomEntriesQuery.gql';
import ContentBlockForm from '@/components/content-block-form/ContentBlockForm';
import { ROOMS_FEATURE_SET } from '@/consts/features.consts';
import { ROOM_PAGE } from '@/router/room.names';
import ContentBlockForm from '@/components/content-block-form/ContentBlockForm';
import {ROOMS_FEATURE_SET} from '@/consts/features.consts';
import {ROOM_PAGE} from '@/router/room.names';
export default Vue.extend({
props: {
slug: {
type: String,
required: true,
export default defineComponent( {
props: {
slug: {
type: String,
required: true
}
},
},
components: {
ContentBlockForm,
},
components: {
ContentBlockForm,
},
data() {
return {
features: ROOMS_FEATURE_SET,
roomEntry: {
title: '',
contents: [],
},
};
},
methods: {
goBack() {
this.$router.push({
name: ROOM_PAGE,
params: {
slug: this.slug,
data() {
return {
features: ROOMS_FEATURE_SET,
roomEntry: {
title: '',
contents: [],
},
});
},
save({ title, contents }) {
const entry = {
title,
contents,
roomSlug: this.slug,
};
this.$apollo
.mutate({
},
methods: {
goBack() {
this.$router.push({
name: ROOM_PAGE,
params: {
slug: this.slug
}
});
},
save({title, contents}) {
const entry = {
title,
contents,
roomSlug: this.slug
};
this.$apollo.mutate({
mutation: NEW_ROOM_ENTRY_MUTATION,
variables: {
input: {
roomEntry: entry,
},
},
update: (
store,
{
data: {
addRoomEntry: { roomEntry },
},
}
) => {
},
update: (store, {data: {addRoomEntry: {roomEntry}}}) => {
try {
const query = ROOM_ENTRIES_QUERY;
const variables = { slug: this.slug };
const { room } = store.readQuery({ query, variables });
const variables = {slug: this.slug};
const {room} = store.readQuery({query, variables});
if (room && room.roomEntries) {
const newEdge = {
const newEdge ={
node: roomEntry,
__typename: 'RoomEntryNodeEdge',
__typename: 'RoomEntryNodeEdge'
};
const edges = [newEdge, ...room.roomEntries.edges];
const edges = [
newEdge,
...room.roomEntries.edges
];
const data = {
room: {
...room,
roomEntries: {
...room.roomEntries,
edges,
},
},
edges
}
}
};
store.writeQuery({ query, variables, data });
store.writeQuery({query, variables, data});
}
} catch (e) {
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
}
},
})
.then(() => {
}
}).then(() => {
this.goBack();
});
}
},
},
});
} );
</script>
<style scoped lang="scss">
@import '~styles/helpers';
@import '~styles/helpers';
</style>