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
This commit is contained in:
parent
eff9d6c52e
commit
a3e970fe7a
|
@ -10,6 +10,7 @@ jobs:
|
||||||
working_directory: ~/pinafore
|
working_directory: ~/pinafore
|
||||||
docker:
|
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
|
# 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/ruby@sha256:b018ec2a8f0bbf06880735d2801402bad316c465edb60663be83ac8f1086b805
|
||||||
- image: circleci/postgres:12.2
|
- image: circleci/postgres:12.2
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { promisify } from 'util'
|
||||||
import childProcessPromise from 'child-process-promise'
|
import childProcessPromise from 'child-process-promise'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { envFile } from './mastodon-config'
|
import { envFile, RUBY_VERSION } from './mastodon-config'
|
||||||
|
|
||||||
const exec = childProcessPromise.exec
|
const exec = childProcessPromise.exec
|
||||||
const stat = promisify(fs.stat)
|
const stat = promisify(fs.stat)
|
||||||
|
@ -10,7 +10,7 @@ const writeFile = promisify(fs.writeFile)
|
||||||
const dir = __dirname
|
const dir = __dirname
|
||||||
|
|
||||||
const GIT_URL = 'https://github.com/tootsuite/mastodon.git'
|
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')
|
const mastodonDir = path.join(dir, '../mastodon')
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ export default async function cloneMastodon () {
|
||||||
console.log('Cloning mastodon...')
|
console.log('Cloning mastodon...')
|
||||||
await exec(`git clone --single-branch --branch ${GIT_TAG} ${GIT_URL} "${mastodonDir}"`)
|
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/.env'), envFile, 'utf8')
|
||||||
|
await writeFile(path.join(dir, '../mastodon/.ruby-version'), RUBY_VERSION, 'utf8')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,3 +14,7 @@ DB_USER=${DB_USER}
|
||||||
DB_NAME=${DB_NAME}
|
DB_NAME=${DB_NAME}
|
||||||
DB_PASS=${DB_PASS}
|
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'
|
||||||
|
|
|
@ -50,6 +50,7 @@ async function runMastodon () {
|
||||||
const env = Object.assign({}, process.env, {
|
const env = Object.assign({}, process.env, {
|
||||||
RAILS_ENV: 'development',
|
RAILS_ENV: 'development',
|
||||||
NODE_ENV: 'development',
|
NODE_ENV: 'development',
|
||||||
|
BUNDLE_PATH: path.join(mastodonDir, 'vendor/bundle'),
|
||||||
DB_NAME,
|
DB_NAME,
|
||||||
DB_USER,
|
DB_USER,
|
||||||
DB_PASS,
|
DB_PASS,
|
||||||
|
@ -58,8 +59,10 @@ async function runMastodon () {
|
||||||
})
|
})
|
||||||
const cwd = mastodonDir
|
const cwd = mastodonDir
|
||||||
const cmds = [
|
const cmds = [
|
||||||
|
'gem update --system',
|
||||||
'gem install bundler foreman',
|
'gem install bundler foreman',
|
||||||
'bundle install --frozen --path vendor/bundle',
|
'bundle config set --local frozen \'true\'',
|
||||||
|
'bundle install',
|
||||||
'bundle exec rails db:migrate',
|
'bundle exec rails db:migrate',
|
||||||
'yarn --pure-lockfile'
|
'yarn --pure-lockfile'
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,8 +4,10 @@ export const homeTimeline = [
|
||||||
{ content: 'pinned toot 1' },
|
{ content: 'pinned toot 1' },
|
||||||
{ content: 'notification of unlisted message' },
|
{ content: 'notification of unlisted message' },
|
||||||
{ content: 'notification of followers-only message' },
|
{ content: 'notification of followers-only message' },
|
||||||
|
{ content: 'notification of direct message' },
|
||||||
{ content: 'this is unlisted' },
|
{ content: 'this is unlisted' },
|
||||||
{ content: 'this is followers-only' },
|
{ content: 'this is followers-only' },
|
||||||
|
{ content: 'direct' },
|
||||||
{ spoiler: 'kitten CW' },
|
{ spoiler: 'kitten CW' },
|
||||||
{ content: 'secret video' },
|
{ content: 'secret video' },
|
||||||
{ content: "here's a video" },
|
{ content: "here's a video" },
|
||||||
|
|
|
@ -22,7 +22,7 @@ test('Shows the home timeline', async t => {
|
||||||
|
|
||||||
await validateTimeline(t, homeTimeline)
|
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 => {
|
test('Shows notifications', async t => {
|
||||||
|
|
|
@ -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 => {
|
test('replies have same privacy as replied-to status by default', async t => {
|
||||||
await loginAsFoobar(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
|
await t
|
||||||
.hover(getNthStatus(1))
|
.click(getNthReplyButton(1 + unlistedIdx))
|
||||||
.hover(getNthStatus(2))
|
.expect(getNthPostPrivacyButton(1 + unlistedIdx).getAttribute('aria-label')).eql(
|
||||||
.click(getNthReplyButton(2))
|
'Adjust privacy (currently Unlisted)'
|
||||||
.expect(getNthPostPrivacyButton(2).getAttribute('aria-label')).eql('Adjust privacy (currently Unlisted)')
|
)
|
||||||
.click(getNthReplyButton(2))
|
.click(getNthReplyButton(1 + unlistedIdx))
|
||||||
.hover(getNthStatus(3))
|
|
||||||
.click(getNthReplyButton(3))
|
await scrollToStatus(t, 1 + privateIdx)
|
||||||
.expect(getNthPostPrivacyButton(3).getAttribute('aria-label')).eql('Adjust privacy (currently Followers-only)')
|
await t
|
||||||
.click(getNthReplyButton(3))
|
.click(getNthReplyButton(1 + privateIdx))
|
||||||
.hover(getNthStatus(4))
|
.expect(getNthPostPrivacyButton(1 + privateIdx).getAttribute('aria-label')).eql(
|
||||||
.hover(getNthStatus(5))
|
'Adjust privacy (currently Followers-only)'
|
||||||
.hover(getNthStatus(6))
|
)
|
||||||
.click(getNthReplyButton(6))
|
.click(getNthReplyButton(1 + privateIdx))
|
||||||
.expect(getNthPostPrivacyButton(6).getAttribute('aria-label')).eql('Adjust privacy (currently Public)')
|
|
||||||
.click(getNthReplyButton(6))
|
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 => {
|
test('replies have same CW as replied-to status', async t => {
|
||||||
await loginAsFoobar(t)
|
await loginAsFoobar(t)
|
||||||
const kittenIdx = homeTimeline.findIndex(_ => _.spoiler === 'kitten CW')
|
const kittenIdx = homeTimeline.findIndex(_ => _.spoiler === 'kitten CW')
|
||||||
|
await t.hover(getNthStatus(1))
|
||||||
await scrollToStatus(t, 1 + kittenIdx)
|
await scrollToStatus(t, 1 + kittenIdx)
|
||||||
await t.click(getNthReplyButton(1 + kittenIdx))
|
await t.click(getNthReplyButton(1 + kittenIdx))
|
||||||
.expect(getNthReplyContentWarningInput(1 + kittenIdx).value).eql('kitten CW')
|
.expect(getNthReplyContentWarningInput(1 + kittenIdx).value).eql('kitten CW')
|
||||||
|
|
|
@ -131,7 +131,7 @@ test('Shortcut . scrolls to top and focuses', async t => {
|
||||||
await scrollToStatus(t, 10)
|
await scrollToStatus(t, 10)
|
||||||
await t
|
await t
|
||||||
.pressKey('.')
|
.pressKey('.')
|
||||||
.expect(isNthStatusActive(1)).ok()
|
.expect(isNthStatusActive(1)()).ok()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Shortcut left and right changes columns', async t => {
|
test('Shortcut left and right changes columns', async t => {
|
||||||
|
|
|
@ -16,8 +16,8 @@ fixture`035-notification-timeline-filters.js`
|
||||||
|
|
||||||
function setSettingAndGoToNotifications (t, setting) {
|
function setSettingAndGoToNotifications (t, setting) {
|
||||||
return t.click(settingsNavButton)
|
return t.click(settingsNavButton)
|
||||||
.click($('a').withText('Instances'))
|
.click($('a[href="/settings/instances"]'))
|
||||||
.click($('a').withText('localhost:3000'))
|
.click($('a[href="/settings/instances/localhost:3000"]'))
|
||||||
.click(setting)
|
.click(setting)
|
||||||
.expect(setting.checked).notOk()
|
.expect(setting.checked).notOk()
|
||||||
.click(notificationsNavButton)
|
.click(notificationsNavButton)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { loginAsFoobar } from '../roles'
|
import { loginAsFoobar } from '../roles'
|
||||||
import { Selector as $ } from 'testcafe'
|
import { Selector as $ } from 'testcafe'
|
||||||
|
import { homeTimeline } from '../fixtures'
|
||||||
|
|
||||||
fixture`036-disable-infinite-load.js`
|
fixture`036-disable-infinite-load.js`
|
||||||
.page`http://localhost:4002`
|
.page`http://localhost:4002`
|
||||||
|
@ -28,12 +29,12 @@ test('Can disable loading items at bottom of timeline', async t => {
|
||||||
await t
|
await t
|
||||||
.click(loadMoreButton)
|
.click(loadMoreButton)
|
||||||
.expect(getActiveElementAriaPosInSet()).eql('40')
|
.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 scrollFromStatusToStatus(t, 40, 47)
|
||||||
await t
|
await t
|
||||||
.click(loadMoreButton)
|
.click(loadMoreButton)
|
||||||
await sleep(1000)
|
await sleep(1000)
|
||||||
await t
|
await t
|
||||||
.expect(loadMoreButton.exists).ok()
|
.expect(loadMoreButton.exists).ok()
|
||||||
.expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql('47')
|
.expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql(homeTimeline.length.toString())
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,7 +22,7 @@ test('autosuggests hashtags', async t => {
|
||||||
.expect(getNthAutosuggestionResult(1).find('.sr-only').innerText).contains('#blank', { timeout })
|
.expect(getNthAutosuggestionResult(1).find('.sr-only').innerText).contains('#blank', { timeout })
|
||||||
.click(getNthAutosuggestionResult(1), { timeout })
|
.click(getNthAutosuggestionResult(1), { timeout })
|
||||||
.expect(composeInput.value).eql('hey #blank ')
|
.expect(composeInput.value).eql('hey #blank ')
|
||||||
.typeText(composeInput, 'and also #BLANK')
|
.typeText(composeInput, 'and also #blank')
|
||||||
.click(getNthAutosuggestionResult(1), { timeout })
|
.click(getNthAutosuggestionResult(1), { timeout })
|
||||||
.expect(composeInput.value).eql('hey #blank and also #blank ')
|
.expect(composeInput.value).eql('hey #blank and also #blank ')
|
||||||
.typeText(composeInput, 'and also #blanka')
|
.typeText(composeInput, 'and also #blanka')
|
||||||
|
|
|
@ -548,15 +548,11 @@ export async function scrollToStatus (t, n) {
|
||||||
|
|
||||||
export async function scrollFromStatusToStatus (t, start, end) {
|
export async function scrollFromStatusToStatus (t, start, end) {
|
||||||
const timeout = 20000
|
const timeout = 20000
|
||||||
for (let i = start; i < end; i++) {
|
for (let i = start; i < end + 1; i++) {
|
||||||
await t.expect(getNthStatus(i).exists).ok({ timeout })
|
await t
|
||||||
|
.expect(getNthStatus(i).exists).ok({ timeout })
|
||||||
.hover(getNthStatus(i))
|
.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) {
|
export async function clickToNotificationsAndBackHome (t) {
|
||||||
|
|
Loading…
Reference in New Issue