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
This commit is contained in:
parent
1c057818c6
commit
708fba989a
84
cypress/integration/widgets.js
Normal file
84
cypress/integration/widgets.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
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">
|
<div class="vjoppmmu">
|
||||||
<template v-if="edit">
|
<template v-if="edit">
|
||||||
<header>
|
<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>
|
<template #label>{{ $ts.selectWidget }}</template>
|
||||||
<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ $t(`_widgets.${widget}`) }}</option>
|
<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ $t(`_widgets.${widget}`) }}</option>
|
||||||
</MkSelect>
|
</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>
|
<MkButton inline @click="$emit('exit')">{{ $ts.close }}</MkButton>
|
||||||
</header>
|
</header>
|
||||||
<XDraggable
|
<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"/>
|
<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-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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<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 #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 #func><button class="_button" @click="toggleView()"><i class="fas fa-sort"></i></button></template>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<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>
|
<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>
|
</MkContainer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<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>
|
<template #header><i class="fas fa-terminal"></i>{{ $ts._widgets.aiscript }}</template>
|
||||||
|
|
||||||
<div class="uylguesu _monospace">
|
<div class="uylguesu _monospace">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<MkContainer :naked="widgetProps.transparent" :show-header="false">
|
<MkContainer :naked="widgetProps.transparent" :show-header="false" class="mkw-clock">
|
||||||
<div class="vubelbmv">
|
<div class="vubelbmv">
|
||||||
<MkAnalogClock class="clock" :thickness="widgetProps.thickness"/>
|
<MkAnalogClock class="clock" :thickness="widgetProps.thickness"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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>
|
<template #header><i class="fas fa-globe"></i>{{ $ts._widgets.federation }}</template>
|
||||||
|
|
||||||
<div class="wbrkwalb">
|
<div class="wbrkwalb">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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>
|
<template #header><i class="fas fa-sticky-note"></i>{{ $ts._widgets.memo }}</template>
|
||||||
|
|
||||||
<div class="otgbylcu">
|
<div class="otgbylcu">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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 #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 #func><button class="_button" @click="configureNotification()"><i class="fas fa-cog"></i></button></template>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<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>
|
<template #header><i class="fas fa-camera"></i>{{ $ts._widgets.photos }}</template>
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<XPostForm class="_panel" :fixed="true" :autofocus="false"/>
|
<XPostForm class="_panel mkw-postForm" :fixed="true" :autofocus="false"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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 #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 #func><button class="_button" @click="configure"><i class="fas fa-cog"></i></button></template>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<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">
|
<div @click="choose">
|
||||||
<p v-if="widgetProps.folderId == null">
|
<p v-if="widgetProps.folderId == null">
|
||||||
{{ $ts.folder }}
|
{{ $ts.folder }}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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>
|
<template #header>
|
||||||
<button class="_button" @click="choose">
|
<button class="_button" @click="choose">
|
||||||
<i v-if="widgetProps.src === 'home'" class="fas fa-home"></i>
|
<i v-if="widgetProps.src === 'home'" class="fas fa-home"></i>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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>
|
<template #header><i class="fas fa-hashtag"></i>{{ $ts._widgets.trends }}</template>
|
||||||
|
|
||||||
<div class="wbrkwala">
|
<div class="wbrkwala">
|
||||||
|
Loading…
Reference in New Issue
Block a user