Skip to content
Snippets Groups Projects
Unverified Commit 708fba98 authored by Andreas Nedbal's avatar Andreas Nedbal Committed by GitHub
Browse files

feat(tests): add e2e tests for widgets (#8735)

* test(e2e): add baseline for widget tests

* chore(repo): enable test running in branch

* fix(e2e): set viewport for widget tests

* fix(client): add widget identifier classes to widgets

* test(e2e): add memo widget test

* fix(tests): force select value

* fix(tests): force button press for widget addition

* fix(tests): invoke select value differently

* fix(tests): adjust widget submit

* fix(tests): don't explicitly navigate for widget test

* fix(tests): click label to hide select popup

* fix(tests): just click modal background

* fix(tests): adjust modal background selector

* fix(tests): click all modal backgrounds

* feat(e2e): add test for adding timeline widget

* fix(client): add more widget identifier classes

* feat(tests): add method abstraction for test cases

* fix(tests): force-click overlays

* fix(tests): force widget button press

* fix(tests): remove timeout from final widget check

* feat(tests): add widget removal test case

* fix(client): use mk instead of msky as class prefix

* fix(tests): check widgets for existence rather than visibility

* chore(meta): don't run tests for specific feature branch
parent 1c057818
No related branches found
No related tags found
No related merge requests found
Showing
with 100 additions and 16 deletions
describe('After user signed in', () => {
beforeEach(() => {
cy.window(win => {
win.indexedDB.deleteDatabase('keyval-store');
});
cy.viewport('macbook-16');
cy.request('POST', '/api/reset-db').as('reset');
cy.get('@reset').its('status').should('equal', 204);
cy.reload(true);
// インスタンス初期セットアップ
cy.request('POST', '/api/admin/accounts/create', {
username: 'admin',
password: 'pass',
}).its('body').as('admin');
// ユーザー作成
cy.request('POST', '/api/signup', {
username: 'alice',
password: 'alice1234',
}).its('body').as('alice');
cy.visit('/');
cy.intercept('POST', '/api/signin').as('signin');
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
cy.wait('@signin').as('signedIn');
});
afterEach(() => {
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
// waitを入れることでそれを防止できる
cy.wait(1000);
});
it('widget edit toggle is visible', () => {
cy.get('.mk-widget-edit').should('be.visible');
});
it('widget select should be visible in edit mode', () => {
cy.get('.mk-widget-edit').click();
cy.get('.mk-widget-select').should('be.visible');
});
it('first widget should be removed', () => {
cy.get('.mk-widget-edit').click();
cy.get('.customize-container:first-child .remove._button').click();
cy.get('.customize-container').should('have.length', 2);
});
function buildWidgetTest(widgetName) {
it(`${widgetName} widget should get added`, () => {
cy.get('.mk-widget-edit').click();
cy.get('.mk-widget-select select').select(widgetName, { force: true });
cy.get('.bg._modalBg.transparent').click({ multiple: true, force: true });
cy.get('.mk-widget-add').click({ force: true });
cy.get(`.mkw-${widgetName}`).should('exist');
});
}
buildWidgetTest('memo');
buildWidgetTest('notifications');
buildWidgetTest('timeline');
buildWidgetTest('calendar');
buildWidgetTest('rss');
buildWidgetTest('trends');
buildWidgetTest('clock');
buildWidgetTest('activity');
buildWidgetTest('photos');
buildWidgetTest('digitalClock');
buildWidgetTest('federation');
buildWidgetTest('postForm');
buildWidgetTest('slideshow');
buildWidgetTest('serverMetric');
buildWidgetTest('onlineUsers');
buildWidgetTest('jobQueue');
buildWidgetTest('button');
buildWidgetTest('aiscript');
buildWidgetTest('aichan');
});
......@@ -2,11 +2,11 @@
<div class="vjoppmmu">
<template v-if="edit">
<header>
<MkSelect v-model="widgetAdderSelected" style="margin-bottom: var(--margin)">
<MkSelect v-model="widgetAdderSelected" style="margin-bottom: var(--margin)" class="mk-widget-select">
<template #label>{{ $ts.selectWidget }}</template>
<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ $t(`_widgets.${widget}`) }}</option>
</MkSelect>
<MkButton inline primary @click="addWidget"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton>
<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton>
<MkButton inline @click="$emit('exit')">{{ $ts.close }}</MkButton>
</header>
<XDraggable
......
......@@ -3,7 +3,7 @@
<XWidgets :edit="editMode" :widgets="defaultStore.reactiveState.widgets.value" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="editMode = false"/>
<button v-if="editMode" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="fas fa-check"></i> {{ i18n.ts.editWidgetsExit }}</button>
<button v-else class="_textButton" style="font-size: 0.9em;" @click="editMode = true"><i class="fas fa-pencil-alt"></i> {{ i18n.ts.editWidgets }}</button>
<button v-else class="_textButton mk-widget-edit" style="font-size: 0.9em;" @click="editMode = true"><i class="fas fa-pencil-alt"></i> {{ i18n.ts.editWidgets }}</button>
</div>
</template>
......
<template>
<MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent">
<MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent" class="mkw-activity">
<template #header><i class="fas fa-chart-bar"></i>{{ $ts._widgets.activity }}</template>
<template #func><button class="_button" @click="toggleView()"><i class="fas fa-sort"></i></button></template>
......
<template>
<MkContainer :naked="widgetProps.transparent" :show-header="false">
<MkContainer :naked="widgetProps.transparent" :show-header="false" class="mkw-aichan">
<iframe ref="live2d" class="dedjhjmo" src="https://misskey-dev.github.io/mascot-web/?scale=1.5&y=1.1&eyeY=100" @click="touched"></iframe>
</MkContainer>
</template>
......
<template>
<MkContainer :show-header="widgetProps.showHeader">
<MkContainer :show-header="widgetProps.showHeader" class="mkw-aiscript">
<template #header><i class="fas fa-terminal"></i>{{ $ts._widgets.aiscript }}</template>
<div class="uylguesu _monospace">
......
<template>
<MkContainer :naked="widgetProps.transparent" :show-header="false">
<MkContainer :naked="widgetProps.transparent" :show-header="false" class="mkw-clock">
<div class="vubelbmv">
<MkAnalogClock class="clock" :thickness="widgetProps.thickness"/>
</div>
......
<template>
<MkContainer :show-header="widgetProps.showHeader" :foldable="foldable" :scrollable="scrollable">
<MkContainer :show-header="widgetProps.showHeader" :foldable="foldable" :scrollable="scrollable" class="mkw-federation">
<template #header><i class="fas fa-globe"></i>{{ $ts._widgets.federation }}</template>
<div class="wbrkwalb">
......
<template>
<MkContainer :show-header="widgetProps.showHeader">
<MkContainer :show-header="widgetProps.showHeader" class="mkw-memo">
<template #header><i class="fas fa-sticky-note"></i>{{ $ts._widgets.memo }}</template>
<div class="otgbylcu">
......
<template>
<MkContainer :style="`height: ${widgetProps.height}px;`" :show-header="widgetProps.showHeader" :scrollable="true">
<MkContainer :style="`height: ${widgetProps.height}px;`" :show-header="widgetProps.showHeader" :scrollable="true" class="mkw-notifications">
<template #header><i class="fas fa-bell"></i>{{ $ts.notifications }}</template>
<template #func><button class="_button" @click="configureNotification()"><i class="fas fa-cog"></i></button></template>
......
<template>
<MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent" :class="$style.root" :data-transparent="widgetProps.transparent ? true : null">
<MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent" :class="$style.root" :data-transparent="widgetProps.transparent ? true : null" class="mkw-photos">
<template #header><i class="fas fa-camera"></i>{{ $ts._widgets.photos }}</template>
<div class="">
......
<template>
<XPostForm class="_panel" :fixed="true" :autofocus="false"/>
<XPostForm class="_panel mkw-postForm" :fixed="true" :autofocus="false"/>
</template>
<script lang="ts" setup>
......
<template>
<MkContainer :show-header="widgetProps.showHeader">
<MkContainer :show-header="widgetProps.showHeader" class="mkw-rss">
<template #header><i class="fas fa-rss-square"></i>RSS</template>
<template #func><button class="_button" @click="configure"><i class="fas fa-cog"></i></button></template>
......
<template>
<div class="kvausudm _panel" :style="{ height: widgetProps.height + 'px' }">
<div class="kvausudm _panel mkw-slideshow" :style="{ height: widgetProps.height + 'px' }">
<div @click="choose">
<p v-if="widgetProps.folderId == null">
{{ $ts.folder }}
......
<template>
<MkContainer :show-header="widgetProps.showHeader" :style="`height: ${widgetProps.height}px;`" :scrollable="true">
<MkContainer :show-header="widgetProps.showHeader" :style="`height: ${widgetProps.height}px;`" :scrollable="true" class="mkw-timeline">
<template #header>
<button class="_button" @click="choose">
<i v-if="widgetProps.src === 'home'" class="fas fa-home"></i>
......
<template>
<MkContainer :show-header="widgetProps.showHeader">
<MkContainer :show-header="widgetProps.showHeader" class="mkw-trends">
<template #header><i class="fas fa-hashtag"></i>{{ $ts._widgets.trends }}</template>
<div class="wbrkwala">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment