From a3e970fe7a8a317a1f81ebc43d5e1806011ad4da Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 24 Jan 2021 18:26:40 -0800 Subject: [PATCH] test: use mastodon 3.3.0 for testing (#1917) * test: use mastodon 3.3.0 for testing * test: fix test * test: fix test * test: fix test * test: fix test * test: revert test change * test: use ruby 2.6.6 --- .circleci/config.yml | 1 + bin/clone-mastodon.js | 5 ++- bin/mastodon-config.js | 4 ++ bin/run-mastodon.js | 5 ++- tests/fixtures.js | 2 + tests/spec/003-basic-timeline-spec.js | 2 +- tests/spec/017-compose-reply.js | 43 ++++++++++++------- tests/spec/024-shortcuts-navigation.js | 2 +- .../spec/035-notification-timeline-filters.js | 4 +- tests/spec/036-disable-infinite-load.js | 5 ++- tests/spec/131-compose-autosuggest.js | 2 +- tests/utils.js | 10 ++--- 12 files changed, 53 insertions(+), 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f7bb291f..f74a8176 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,6 +10,7 @@ jobs: working_directory: ~/pinafore docker: # see https://discuss.circleci.com/t/build-failed-the-engine-node-is-incompatible-with-this-module-expected-version-12-x-got-14-15-0/37921/7 + # we want Node v12, not v14 - image: circleci/ruby@sha256:b018ec2a8f0bbf06880735d2801402bad316c465edb60663be83ac8f1086b805 - image: circleci/postgres:12.2 environment: diff --git a/bin/clone-mastodon.js b/bin/clone-mastodon.js index 31fbfe18..151a3349 100644 --- a/bin/clone-mastodon.js +++ b/bin/clone-mastodon.js @@ -2,7 +2,7 @@ import { promisify } from 'util' import childProcessPromise from 'child-process-promise' import path from 'path' import fs from 'fs' -import { envFile } from './mastodon-config' +import { envFile, RUBY_VERSION } from './mastodon-config' const exec = childProcessPromise.exec const stat = promisify(fs.stat) @@ -10,7 +10,7 @@ const writeFile = promisify(fs.writeFile) const dir = __dirname const GIT_URL = 'https://github.com/tootsuite/mastodon.git' -const GIT_TAG = 'v3.1.3' +const GIT_TAG = 'v3.3.0' const mastodonDir = path.join(dir, '../mastodon') @@ -21,6 +21,7 @@ export default async function cloneMastodon () { console.log('Cloning mastodon...') await exec(`git clone --single-branch --branch ${GIT_TAG} ${GIT_URL} "${mastodonDir}"`) await writeFile(path.join(dir, '../mastodon/.env'), envFile, 'utf8') + await writeFile(path.join(dir, '../mastodon/.ruby-version'), RUBY_VERSION, 'utf8') } } diff --git a/bin/mastodon-config.js b/bin/mastodon-config.js index 44c98f68..1b846482 100644 --- a/bin/mastodon-config.js +++ b/bin/mastodon-config.js @@ -14,3 +14,7 @@ DB_USER=${DB_USER} DB_NAME=${DB_NAME} DB_PASS=${DB_PASS} ` + +// Need a Ruby version that CircleCI bundles with Node v12, not Node v14 which doesn't +// work for streaming +export const RUBY_VERSION = '2.6.6' diff --git a/bin/run-mastodon.js b/bin/run-mastodon.js index 60adf310..ef0818d3 100644 --- a/bin/run-mastodon.js +++ b/bin/run-mastodon.js @@ -50,6 +50,7 @@ async function runMastodon () { const env = Object.assign({}, process.env, { RAILS_ENV: 'development', NODE_ENV: 'development', + BUNDLE_PATH: path.join(mastodonDir, 'vendor/bundle'), DB_NAME, DB_USER, DB_PASS, @@ -58,8 +59,10 @@ async function runMastodon () { }) const cwd = mastodonDir const cmds = [ + 'gem update --system', 'gem install bundler foreman', - 'bundle install --frozen --path vendor/bundle', + 'bundle config set --local frozen \'true\'', + 'bundle install', 'bundle exec rails db:migrate', 'yarn --pure-lockfile' ] diff --git a/tests/fixtures.js b/tests/fixtures.js index d1fbfb41..39c532eb 100644 --- a/tests/fixtures.js +++ b/tests/fixtures.js @@ -4,8 +4,10 @@ export const homeTimeline = [ { content: 'pinned toot 1' }, { content: 'notification of unlisted message' }, { content: 'notification of followers-only message' }, + { content: 'notification of direct message' }, { content: 'this is unlisted' }, { content: 'this is followers-only' }, + { content: 'direct' }, { spoiler: 'kitten CW' }, { content: 'secret video' }, { content: "here's a video" }, diff --git a/tests/spec/003-basic-timeline-spec.js b/tests/spec/003-basic-timeline-spec.js index 80bdacca..259efa7e 100644 --- a/tests/spec/003-basic-timeline-spec.js +++ b/tests/spec/003-basic-timeline-spec.js @@ -22,7 +22,7 @@ test('Shows the home timeline', async t => { await validateTimeline(t, homeTimeline) - await t.expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql('47') + await t.expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql(homeTimeline.length.toString()) }) test('Shows notifications', async t => { diff --git a/tests/spec/017-compose-reply.js b/tests/spec/017-compose-reply.js index 71ab4873..36d261e9 100644 --- a/tests/spec/017-compose-reply.js +++ b/tests/spec/017-compose-reply.js @@ -42,27 +42,40 @@ test('replying to posts with mentions', async t => { test('replies have same privacy as replied-to status by default', async t => { await loginAsFoobar(t) + const unlistedIdx = homeTimeline.findIndex(_ => _.content === 'notification of unlisted message') + const privateIdx = homeTimeline.findIndex(_ => _.content === 'notification of followers-only message') + const publicIdx = homeTimeline.findIndex(_ => _.spoiler === 'kitten CW') + + await t.hover(getNthStatus(1)) + await scrollToStatus(t, 1 + unlistedIdx) await t - .hover(getNthStatus(1)) - .hover(getNthStatus(2)) - .click(getNthReplyButton(2)) - .expect(getNthPostPrivacyButton(2).getAttribute('aria-label')).eql('Adjust privacy (currently Unlisted)') - .click(getNthReplyButton(2)) - .hover(getNthStatus(3)) - .click(getNthReplyButton(3)) - .expect(getNthPostPrivacyButton(3).getAttribute('aria-label')).eql('Adjust privacy (currently Followers-only)') - .click(getNthReplyButton(3)) - .hover(getNthStatus(4)) - .hover(getNthStatus(5)) - .hover(getNthStatus(6)) - .click(getNthReplyButton(6)) - .expect(getNthPostPrivacyButton(6).getAttribute('aria-label')).eql('Adjust privacy (currently Public)') - .click(getNthReplyButton(6)) + .click(getNthReplyButton(1 + unlistedIdx)) + .expect(getNthPostPrivacyButton(1 + unlistedIdx).getAttribute('aria-label')).eql( + 'Adjust privacy (currently Unlisted)' + ) + .click(getNthReplyButton(1 + unlistedIdx)) + + await scrollToStatus(t, 1 + privateIdx) + await t + .click(getNthReplyButton(1 + privateIdx)) + .expect(getNthPostPrivacyButton(1 + privateIdx).getAttribute('aria-label')).eql( + 'Adjust privacy (currently Followers-only)' + ) + .click(getNthReplyButton(1 + privateIdx)) + + await scrollToStatus(t, 1 + publicIdx) + await t + .click(getNthReplyButton(1 + publicIdx)) + .expect(getNthPostPrivacyButton(1 + publicIdx).getAttribute('aria-label')).eql( + 'Adjust privacy (currently Public)' + ) + .click(getNthReplyButton(1 + publicIdx)) }) test('replies have same CW as replied-to status', async t => { await loginAsFoobar(t) const kittenIdx = homeTimeline.findIndex(_ => _.spoiler === 'kitten CW') + await t.hover(getNthStatus(1)) await scrollToStatus(t, 1 + kittenIdx) await t.click(getNthReplyButton(1 + kittenIdx)) .expect(getNthReplyContentWarningInput(1 + kittenIdx).value).eql('kitten CW') diff --git a/tests/spec/024-shortcuts-navigation.js b/tests/spec/024-shortcuts-navigation.js index 208b8658..12aa23cb 100644 --- a/tests/spec/024-shortcuts-navigation.js +++ b/tests/spec/024-shortcuts-navigation.js @@ -131,7 +131,7 @@ test('Shortcut . scrolls to top and focuses', async t => { await scrollToStatus(t, 10) await t .pressKey('.') - .expect(isNthStatusActive(1)).ok() + .expect(isNthStatusActive(1)()).ok() }) test('Shortcut left and right changes columns', async t => { diff --git a/tests/spec/035-notification-timeline-filters.js b/tests/spec/035-notification-timeline-filters.js index f7888c5c..6d81d3a0 100644 --- a/tests/spec/035-notification-timeline-filters.js +++ b/tests/spec/035-notification-timeline-filters.js @@ -16,8 +16,8 @@ fixture`035-notification-timeline-filters.js` function setSettingAndGoToNotifications (t, setting) { return t.click(settingsNavButton) - .click($('a').withText('Instances')) - .click($('a').withText('localhost:3000')) + .click($('a[href="/settings/instances"]')) + .click($('a[href="/settings/instances/localhost:3000"]')) .click(setting) .expect(setting.checked).notOk() .click(notificationsNavButton) diff --git a/tests/spec/036-disable-infinite-load.js b/tests/spec/036-disable-infinite-load.js index f6cb47d0..fb498f1b 100644 --- a/tests/spec/036-disable-infinite-load.js +++ b/tests/spec/036-disable-infinite-load.js @@ -7,6 +7,7 @@ import { } from '../utils' import { loginAsFoobar } from '../roles' import { Selector as $ } from 'testcafe' +import { homeTimeline } from '../fixtures' fixture`036-disable-infinite-load.js` .page`http://localhost:4002` @@ -28,12 +29,12 @@ test('Can disable loading items at bottom of timeline', async t => { await t .click(loadMoreButton) .expect(getActiveElementAriaPosInSet()).eql('40') - .expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql('47') + .expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql(homeTimeline.length.toString()) await scrollFromStatusToStatus(t, 40, 47) await t .click(loadMoreButton) await sleep(1000) await t .expect(loadMoreButton.exists).ok() - .expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql('47') + .expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql(homeTimeline.length.toString()) }) diff --git a/tests/spec/131-compose-autosuggest.js b/tests/spec/131-compose-autosuggest.js index 3e61f3a6..da343f0f 100644 --- a/tests/spec/131-compose-autosuggest.js +++ b/tests/spec/131-compose-autosuggest.js @@ -22,7 +22,7 @@ test('autosuggests hashtags', async t => { .expect(getNthAutosuggestionResult(1).find('.sr-only').innerText).contains('#blank', { timeout }) .click(getNthAutosuggestionResult(1), { timeout }) .expect(composeInput.value).eql('hey #blank ') - .typeText(composeInput, 'and also #BLANK') + .typeText(composeInput, 'and also #blank') .click(getNthAutosuggestionResult(1), { timeout }) .expect(composeInput.value).eql('hey #blank and also #blank ') .typeText(composeInput, 'and also #blanka') diff --git a/tests/utils.js b/tests/utils.js index 59f8ca71..3c21394d 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -548,15 +548,11 @@ export async function scrollToStatus (t, n) { export async function scrollFromStatusToStatus (t, start, end) { const timeout = 20000 - for (let i = start; i < end; i++) { - await t.expect(getNthStatus(i).exists).ok({ timeout }) + for (let i = start; i < end + 1; i++) { + await t + .expect(getNthStatus(i).exists).ok({ timeout }) .hover(getNthStatus(i)) - .expect($(`${getNthStatusSelector(i)} .status-toolbar`).exists).ok({ timeout }) - .hover($(`${getNthStatusSelector(i)} .status-toolbar`)) } - await t - .expect(getNthStatus(end).exists).ok({ timeout }) - .hover(getNthStatus(end)) } export async function clickToNotificationsAndBackHome (t) {