Fix old cypress test

Also add new scripts for sorry-cypress
This commit is contained in:
Ramon Wenger 2021-08-16 20:43:45 +02:00
parent 605bde9e95
commit ca522d385b
12 changed files with 348 additions and 226 deletions

32
bin/test-sorry-cypress.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
cd client/
if [[ -z "${CYPRESS_API_URL+x}" ]]; then
echo "CYPRESS_API_URL not set"
exit 1
fi
if [[ -z "${CYPRESS_RECORD_KEY+x}" ]]; then
echo "CYPRESS_RECORD_KEY not set"
exit 2
fi
now=`date +%F-%T`
build_id="skillbox-build-${now}"
#CYPRESS_API_URL="https://iterativ-cypress-director.herokuapp.com/"
#cmd=""
cmd() {
npx cy2 run --parallel --record --config-file cypress.frontend.json --ci-build-id ${build_id}
}
#cmd
for number in {1..6}
do
echo "running command ${number}"
cmd &
done
wait
#exit 0

View File

@ -6,6 +6,7 @@
"mochaFile": "cypress/test-reports/e2e/cypress-results-[hash].xml",
"toConsole": true
},
"projectId": "msk-ee",
"integrationFolder": "cypress/integration/e2e",
"$schema": "https://on.cypress.io/cypress.schema.json"
}

View File

@ -6,6 +6,7 @@
"mochaFile": "cypress/test-reports/frontend/cypress-results-[hash].xml",
"toConsole": true
},
"projectId": "msk-fe",
"integrationFolder": "cypress/integration/frontend",
"$schema": "https://on.cypress.io/cypress.schema.json"
}

View File

@ -3,48 +3,41 @@ const selectedClass = {
name: 'Moordale',
readOnly: false,
code: 'XXXX',
members: []
members: [],
};
let classMemberIndex = 0;
let idIndex = 0;
function* classMemberIdGenerator() {
while (classMemberIndex < 99) {
classMemberIndex += 1;
yield btoa(`ClassMemberNode:${classMemberIndex}`);
function* idGenerator(entity) {
while (true) {
console.log(`generating id for ${entity}, ${idIndex}`);
idIndex += 1;
yield btoa(`${entity}:${idIndex}`);
}
}
const classMemberIdIterator = classMemberIdGenerator();
const classMemberIdIterator = idGenerator('ClassMemberNode');
const chapterIdIterator = idGenerator('ChapterNode');
const moduleIdIterator = idGenerator('ModuleNode');
const contentBlockIdIterator = idGenerator('ContentBlockNode');
const getClassMemberId = () => {
return classMemberIdIterator.next().value;
};
const getClassMemberId = () => classMemberIdIterator.next().value;
const getChapterId = () => chapterIdIterator.next().value;
const getModuleId = () => moduleIdIterator.next().value;
const getContentBlockId = () => contentBlockIdIterator.next().value;
export default {
UUID: () => '123-456-789',
GenericStreamFieldType: () => ({type: 'text_block', value: 'Generic Stream Field Type'}),
DateTime: () => '2021-01-01Z10:01:23',
SnapshotNode: () => ({
// id: ID!
// module: ModuleNode!
chapters: [],
// chapters: [SnapshotChapterNode]
// hiddenContentBlocks(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ContentBlockNodeConnection!
// created: DateTime!
// creator: String!
// shared: Boolean!
// objectiveGroups: [SnapshotObjectiveGroupNode]
// hiddenObjectives(offset: Int, before: String, after: String, first: Int, last: Int, text: String): ObjectiveNodeConnection!
title: 'MockSnapshotTitle',
metaTitle: 'MockSnapshotMetaTitle',
// heroImage: String
// changes: SnapshotChangesNode
// mine: Boolean
}),
ChapterNode: () => ({
slug: 'chapter-slug',
id: 'chapter-id',
id: getChapterId(),
title: 'chapter-title',
description: 'chapter-description',
@ -55,7 +48,7 @@ export default {
slug: 'content-block-slug',
userCreated: false,
type: '',
id: 'content-block-id',
id: getContentBlockId(),
}),
AssignmentNode: () => ({
id: 'assignment-id',
@ -69,12 +62,15 @@ export default {
selectedClass,
schoolClasses: {
edges: [
{node: selectedClass}
]
{node: selectedClass},
],
},
recentModules: {
edges: []
}
}),
SchoolClassNode: () => ({
readOnly: false
readOnly: false,
}),
ClassMemberNode: () => ({
firstName: 'First Name',
@ -82,6 +78,21 @@ export default {
active: true,
isTeacher: false,
isMe: false,
id: getClassMemberId()
id: getClassMemberId(),
}),
ModuleNode: () => ({
title: 'Module Title',
slug: 'some slug',
metaTitle: 'Meta Title',
heroImage: '',
teaser: '',
intro: '',
assignments: {nodes: []},
id: getModuleId(),
}),
TopicNode: () => ({
modules: {
edges: []
}
})
};

View File

@ -1,27 +0,0 @@
{
"topics": {
"edges": [
{
"node": {
"id": "VG9waWNOb2RlOjU=",
"order": 1,
"title": "Geld und Kauf",
"slug": "geld-und-kauf",
"__typename": "TopicNode"
},
"__typename": "TopicEdge"
},
{
"node": {
"id": "VG9waWNOb2RlOjUz",
"order": 2,
"title": "Berufliche Grundbildung",
"slug": "berufliche-grundbildung",
"__typename": "TopicNode"
},
"__typename": "TopicEdge"
}
],
"__typename": "TopicConnection"
}
}

View File

@ -1,166 +1,205 @@
const assignments = require('../../fixtures/assignments.json');
const mePayload = require('../../fixtures/me.join-class.json');
const topics = require('../../fixtures/topics.json');
const baseTopic = require('../../fixtures/geld-und-kauf.json');
const topics = [
{
id: 'VG9waWNOb2RlOjU=',
order: 1,
title: 'Geld und Kauf',
slug: 'geld-und-kauf',
},
{
id: 'VG9waWNOb2RlOjUz',
order: 2,
title: 'Berufliche Grundbildung',
slug: 'berufliche-grundbildung',
},
];
const moduleTeasers = require('../../fixtures/module-teasers.json');
const fullModules = require('../../fixtures/full-modules.json');
let recentModules = [];
const topic = {
topic: {
...baseTopic.topic,
modules: {
'__typename': 'ModuleNodeConnection',
edges: [
...Object.values(moduleTeasers).map(module => {
const me = () => {
console.log('getting me');
return {
node: module,
__typename: 'ModuleNodeEdge',
};
}),
],
},
},
};
const me = {
...mePayload.me,
lastModule: {
// 'id': 'TW9kdWxlTm9kZToxNw==',
'slug': 'lohn-und-budget',
'__typename': 'ModuleNode',
slug: 'lohn-und-budget',
id: 'last-module-id',
},
lastTopic: {
'id': 'VG9waWNOb2RlOjU=',
'slug': 'geld-und-kauf',
'__typename': 'TopicNode',
id: 'VG9waWNOb2RlOjU=',
slug: 'geld-und-kauf',
},
recentModules: {
'edges': [],
'__typename': 'ModuleNodeConnection',
edges: recentModules,
},
};
};
const getId = (id) => btoa(`ModuleNode:${id}`);
const modules = {
[getId(1)]: {
title: 'Lohn und Budget',
metaTitle: 'Modul 1',
slug: 'lohn-und-budget',
id: getId(1),
},
[getId(2)]: {
title: 'Geld',
metaTitle: 'Modul 2',
slug: 'geld',
id: getId(2),
},
[getId(3)]: {
title: 'Lerntipps',
metaTitle: 'Modul 4',
slug: 'lerntipps',
id: getId(3),
},
[getId(4)]: {
title: 'Random',
metaTitle: 'Modul 5',
slug: 'random',
id: getId(4),
},
};
const operations = {
MeQuery: variables => {
return {
me: {
...me,
'__typename': 'UserNode',
'permissions': [],
const slugs = {
'lohn-und-budget': getId(1),
'geld': getId(2),
'lerntipps': getId(3),
'random': getId(4),
};
const getModuleBySlug = (slug) => {
console.log('getModuleBySlug', slug);
const id = slugs[slug];
console.log(id);
return modules[id];
};
const moduleNodes = Object.values(modules).map(module => ({
node: module,
}));
console.log(moduleNodes);
const getTopic = () => ({
topic: {
title: 'Geld und Kauf',
id: 'VG9waWNOb2RlOjU=',
teaser: 'Topic 2',
modules: {
edges: moduleNodes,
},
};
},
});
const getOperations = () => ({
MeQuery: {
me: me(),
},
AssignmentsQuery: {
assignments,
assignments: [],
},
ModulesQuery: variables => {
ModuleDetailsQuery: variables => ({module: getModuleBySlug(variables.slug)}),
TopicsQuery: {
topics: {
edges: topics.map(topic => ({node: topic})),
},
},
Topic: getTopic(),
UpdateLastTopic: () => {
const Topic = getTopic();
const topic = Topic.topic;
return {
module: fullModules[variables.slug],
updateLastTopic: {
topic,
},
};
},
TopicsQuery: topics,
Topic: topic,
UpdateLastTopic: {
'updateLastTopic': {
'topic': topic.topic,
'__typename': 'UpdateLastTopicPayload',
NewsTeasers: {
newsTeasers: {
edges: [],
},
},
UpdateLastModule: variables => {
UpdateLastModule: ({input: {id}}) => {
const lastModule = modules[id];
return {
updateLastModule: {
lastModule: moduleTeasers[variables.input.id],
__typename: 'UpdateLastModulePayload',
lastModule,
},
};
},
};
});
Cypress.Commands.add('checkHome', (n, skipHome) => {
const checkHome = (n, skipHome) => {
cy.log(`Checking if home has ${n} teasers`);
if (!skipHome) {
cy.get('[data-cy="home-link"]').click();
}
cy.get('[data-cy=start-modules-list]').should('exist');
cy.get('[data-cy=start-module-teaser]').should('have.length', n);
});
};
Cypress.Commands.add('goToModule', (topicTitle, moduleMetaTitle) => {
const goToModule = (topicTitle, moduleMetaTitle) => {
cy.log(`Going to module ${moduleMetaTitle} in topic ${topicTitle}`);
cy.get('[data-cy=open-sidebar-link]').click();
cy.contains(topicTitle).click();
cy.get('[data-cy=topic-title]').should('exist').should('contain', topicTitle);
cy.contains(moduleMetaTitle).click();
});
};
describe('Current Module', () => {
before(() => {
cy.server();
cy.task('getSchema').then(schema => {
cy.mockGraphql({
schema,
// endpoint: '/api/graphql'
// mocks,
operations,
});
cy.setup();
});
// cy.mockGraphql({
// schema: schema,
// // endpoint: '/api/graphql'
// operations,
// });
it('is set correctly', () => {
cy.mockGraphqlOps({
operations: getOperations(),
});
// it('is set correctly', () => {
// cy.viewport('macbook-15');
//
// cy.fakeLogin('ross.geller', 'test');
// // cy.apolloLogin('ross.geller', 'test');
// cy.visit('/');
//
// // module list exists, but does not have anything in it
// cy.checkHome(0, true);
// cy.get('[data-cy=no-modules-yet]').should('exist').should('contain', 'Sie haben sich noch kein Modul angeschaut. Legen Sie jetzt los!');
//
// cy.goToModule('Geld und Kauf', 'Modul 2');
// cy.get('[data-cy=module-title]').should('contain', 'Geld');
// cy.checkHome(1);
// cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
//
// cy.goToModule('Geld und Kauf', 'Modul 1');
// cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
// cy.checkHome(2);
// cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lohn und Budget');
// cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
//
// cy.goToModule('Geld und Kauf', 'Modul 4');
// cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
// cy.checkHome(3);
// cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
// cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lohn und Budget');
// cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
//
// // module list is full, should switch only the order around
// cy.goToModule('Geld und Kauf', 'Modul 2');
// cy.get('[data-cy=module-title]').should('contain', 'Geld');
// cy.checkHome(3);
// cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
// cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lerntipps');
// cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lohn und Budget');
//
// cy.goToModule('Geld und Kauf', 'Modul 5');
// cy.get('[data-cy=module-title]').should('contain', 'Random');
// cy.checkHome(3);
// cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Random');
// cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
// cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lerntipps');
//
// cy.get('[data-cy=start-module-teaser]').last().click();
// cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
// cy.checkHome(3);
// cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
// cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Random');
// cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
// });
cy.visit('/');
// module list exists, but does not have anything in it
checkHome(0, true);
cy.get('[data-cy=no-modules-yet]').should('exist').should('contain', 'Sie haben sich noch kein Modul angeschaut. Legen Sie jetzt los!');
goToModule('Geld und Kauf', 'Modul 2');
cy.get('[data-cy=module-title]').should('contain', 'Geld');
checkHome(1);
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
goToModule('Geld und Kauf', 'Modul 1');
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
checkHome(2);
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lohn und Budget');
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
goToModule('Geld und Kauf', 'Modul 4');
cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
checkHome(3);
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lohn und Budget');
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
// module list is full, should switch only the order around
goToModule('Geld und Kauf', 'Modul 2');
cy.get('[data-cy=module-title]').should('contain', 'Geld');
checkHome(3);
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lerntipps');
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lohn und Budget');
goToModule('Geld und Kauf', 'Modul 5');
cy.get('[data-cy=module-title]').should('contain', 'Random');
checkHome(3);
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Random');
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lerntipps');
cy.get('[data-cy=start-module-teaser]').last().click();
cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
checkHome(3);
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Random');
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
});
});

View File

@ -1,18 +1,6 @@
import getMe from '../../fixtures/me.minimal';
import module from '../../fixtures/module.minimal';
import mocks from '../../fixtures/mocks';
// title: String
// slug: String!
// hiddenFor: [SchoolClassNode]
// visibleFor: [SchoolClassNode]
// userCreated: Boolean!
// contents: GenericStreamFieldType
// type: String
// id: ID!
// mine: Boolean
// bookmarks: [ContentBlockBookmarkNode]
// originalCreator: PublicUserNode
const chapters = [{
title: 'ABC',
description: 'DEF',
@ -43,17 +31,10 @@ const operations = {
describe('Custom Content Block', () => {
before(() => {
cy.task('getSchema').then(schema => {
cy.mockGraphql({
schema,
mocks,
operations,
});
});
cy.viewport('macbook-15');
cy.setup();
});
it.skip('Deletes the custom content block and removes it from the view', () => {
it('Deletes the custom content block and removes it from the view', () => {
cy.fakeLogin('ross.geller', 'test');
cy.visit('module/some-module');

View File

@ -3,7 +3,7 @@
"allowJs": true,
"checkJs": true,
"resolveJsonModule": true,
"lib": ["es2015", "dom"],
"lib": ["es2017", "dom"],
"target": "ES5",
"types": [
"cypress"

View File

@ -7967,6 +7967,30 @@
"array-find-index": "^1.0.1"
}
},
"cy2": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/cy2/-/cy2-1.2.1.tgz",
"integrity": "sha512-wT99aBDkMcsmbAYK6mwfDTbH43tN/hyaJ2NrLYfjid9bDTx3rn7UaPKWOIRZtT7L2v32zbMp/GTRtHO3HWb23Q==",
"requires": {
"js-yaml": "^4.0.0",
"npm-which": "^3.0.1"
},
"dependencies": {
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"requires": {
"argparse": "^2.0.1"
}
}
}
},
"cyclist": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
@ -16090,6 +16114,14 @@
"npm-bundled": "^1.0.1"
}
},
"npm-path": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz",
"integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==",
"requires": {
"which": "^1.2.10"
}
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@ -16098,6 +16130,16 @@
"path-key": "^2.0.0"
}
},
"npm-which": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz",
"integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=",
"requires": {
"commander": "^2.9.0",
"npm-path": "^2.0.2",
"which": "^1.2.10"
}
},
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",

View File

@ -19,7 +19,8 @@
"cypress:e2e:test": "cypress run --config-file cypress.e2e.json",
"cypress:frontend:test": "cypress run --config-file cypress.frontend.json",
"install:cypress": "cypress install",
"test:unit": "jest"
"test:unit": "jest",
"cypress:parallel": "CYPRESS_API_URL=\"https://iterativ-cypress-director.herokuapp.com/\" cy2 run --parallel --record --key somekey --config-file cypress.frontend.json --ci-build-id some-id"
},
"dependencies": {
"@babel/core": "^7.5.4",
@ -44,6 +45,7 @@
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"cy2": "^1.2.1",
"dayjs": "^1.10.4",
"debounce": "^1.2.0",
"eslint": "^4.15.0",

View File

@ -1,9 +1,13 @@
<template>
<div v-if="module.id">
<module
:module="module"
v-if="module.id"
@editNote="editNote"
@addNote="addNote"
@bookmark="bookmark"/>
</div>
</template>
<script>
@ -18,12 +22,13 @@
import meMixin from '@/mixins/me';
import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery';
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
export default {
mixins: [meMixin],
components: {
Module
Module,
},
data() {
@ -32,10 +37,6 @@
};
},
created() {
this.updateLastVisitedModule(this.module.id);
},
apollo: {
module() {
return {
@ -46,9 +47,8 @@
update(data) {
return this.$getRidOfEdges(data).module || {};
},
result() {
// scroll only after the module has been loaded completely
// this.scrollTo();
result({data: {module: {id}}}) {
this.updateLastVisitedModule(id);
},
fetchPolicy: 'cache-first',
};
@ -61,6 +61,7 @@
methods: {
updateLastVisitedModule(moduleId) {
if (!moduleId) {
this.$log.warn('no module id');
return;
}
this.$apollo.mutate({
@ -70,6 +71,45 @@
id: moduleId,
},
},
update: (store, {data: {updateLastModule: {lastModule}}}) => {
const {id, slug} = lastModule;
this.$log.debug('updating last module', id, slug);
const query = ME_QUERY;
let {me} = store.readQuery({
query,
});
me.lastModule = {
id,
slug,
__typename: 'ModuleNode',
};
if (!me.recentModules || !me.recentModules.edges) {
me.recentModules = {
__typename: 'ModuleNodeConnection',
edges: [],
};
}
const foundIndex = me.recentModules.edges.findIndex(edge => edge.node.slug === lastModule.slug);
let edges = me.recentModules.edges;
if (foundIndex > -1) {
edges = [...edges.slice(0, foundIndex), ...edges.slice(foundIndex + 1, edges.length)];
}
me.recentModules.edges = [
{
node: lastModule,
__typename: 'ModuleNodeEdge',
},
...edges.slice(0, 2),
];
store.writeQuery({
query,
data: {
me,
},
});
},
});
},
bookmark(bookmarked) {

View File

@ -31,7 +31,7 @@
</div>
<div class="topic__modules">
<module-teaser
:key="module.id"
:key="module.slug"
v-bind="module"
v-for="module in modules"/>
</div>