chore(travis): update to mastodon v2.6.1 (#630)
* chore(travis): update to mastodon v2.6.1 * check if mastodon v2.6.1 has a race condition * apparently in 2.6.1 direct messages no longer appear in home timeline * Revert "check if mastodon v2.6.1 has a race condition" This reverts commit dde8ef8be58eda0563170e6b73165fdcbea54f6b. * try to fix tests * fix more tests
This commit is contained in:
parent
1fa37df59a
commit
0964442815
|
@ -14,7 +14,7 @@ const writeFile = pify(fs.writeFile.bind(fs))
|
|||
const dir = __dirname
|
||||
|
||||
const GIT_URL = 'https://github.com/tootsuite/mastodon.git'
|
||||
const GIT_TAG = 'v2.5.0'
|
||||
const GIT_TAG = 'v2.6.1'
|
||||
|
||||
const DB_NAME = 'pinafore_development'
|
||||
const DB_USER = 'pinafore'
|
||||
|
|
|
@ -8,8 +8,8 @@ fi
|
|||
|
||||
# install ruby
|
||||
source "$HOME/.rvm/scripts/rvm"
|
||||
rvm install 2.5.1
|
||||
rvm use 2.5.1
|
||||
rvm install 2.5.3
|
||||
rvm use 2.5.3
|
||||
|
||||
# fix for redis IPv6 issue
|
||||
# https://travis-ci.community/t/trusty-environment-redis-server-not-starting-with-redis-tools-installed/650/2
|
||||
|
|
|
@ -82,6 +82,45 @@ SET default_tablespace = '';
|
|||
|
||||
SET default_with_oids = false;
|
||||
|
||||
--
|
||||
-- Name: account_conversations; Type: TABLE; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE TABLE public.account_conversations (
|
||||
id bigint NOT NULL,
|
||||
account_id bigint,
|
||||
conversation_id bigint,
|
||||
participant_account_ids bigint[] DEFAULT '{}'::bigint[] NOT NULL,
|
||||
status_ids bigint[] DEFAULT '{}'::bigint[] NOT NULL,
|
||||
last_status_id bigint,
|
||||
lock_version integer DEFAULT 0 NOT NULL,
|
||||
unread boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
ALTER TABLE public.account_conversations OWNER TO pinafore;
|
||||
|
||||
--
|
||||
-- Name: account_conversations_id_seq; Type: SEQUENCE; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.account_conversations_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
ALTER TABLE public.account_conversations_id_seq OWNER TO pinafore;
|
||||
|
||||
--
|
||||
-- Name: account_conversations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.account_conversations_id_seq OWNED BY public.account_conversations.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_domain_blocks; Type: TABLE; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -558,7 +597,8 @@ CREATE TABLE public.domain_blocks (
|
|||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
severity integer DEFAULT 0,
|
||||
reject_media boolean DEFAULT false NOT NULL
|
||||
reject_media boolean DEFAULT false NOT NULL,
|
||||
reject_reports boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
|
@ -976,7 +1016,8 @@ CREATE TABLE public.mentions (
|
|||
status_id bigint,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
account_id bigint
|
||||
account_id bigint,
|
||||
silent boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
|
@ -1202,6 +1243,43 @@ ALTER TABLE public.oauth_applications_id_seq OWNER TO pinafore;
|
|||
ALTER SEQUENCE public.oauth_applications_id_seq OWNED BY public.oauth_applications.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: pghero_space_stats; Type: TABLE; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE TABLE public.pghero_space_stats (
|
||||
id bigint NOT NULL,
|
||||
database text,
|
||||
schema text,
|
||||
relation text,
|
||||
size bigint,
|
||||
captured_at timestamp without time zone
|
||||
);
|
||||
|
||||
|
||||
ALTER TABLE public.pghero_space_stats OWNER TO pinafore;
|
||||
|
||||
--
|
||||
-- Name: pghero_space_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.pghero_space_stats_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
ALTER TABLE public.pghero_space_stats_id_seq OWNER TO pinafore;
|
||||
|
||||
--
|
||||
-- Name: pghero_space_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.pghero_space_stats_id_seq OWNED BY public.pghero_space_stats.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: preview_cards; Type: TABLE; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -1890,6 +1968,13 @@ ALTER TABLE public.web_settings_id_seq OWNER TO pinafore;
|
|||
ALTER SEQUENCE public.web_settings_id_seq OWNED BY public.web_settings.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_conversations id; Type: DEFAULT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.account_conversations ALTER COLUMN id SET DEFAULT nextval('public.account_conversations_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_domain_blocks id; Type: DEFAULT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -2086,6 +2171,13 @@ ALTER TABLE ONLY public.oauth_access_tokens ALTER COLUMN id SET DEFAULT nextval(
|
|||
ALTER TABLE ONLY public.oauth_applications ALTER COLUMN id SET DEFAULT nextval('public.oauth_applications_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: pghero_space_stats id; Type: DEFAULT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.pghero_space_stats ALTER COLUMN id SET DEFAULT nextval('public.pghero_space_stats_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: preview_cards id; Type: DEFAULT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -2191,6 +2283,14 @@ ALTER TABLE ONLY public.web_push_subscriptions ALTER COLUMN id SET DEFAULT nextv
|
|||
ALTER TABLE ONLY public.web_settings ALTER COLUMN id SET DEFAULT nextval('public.web_settings_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: account_conversations; Type: TABLE DATA; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
COPY public.account_conversations (id, account_id, conversation_id, participant_account_ids, status_ids, last_status_id, lock_version, unread) FROM stdin;
|
||||
\.
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: account_domain_blocks; Type: TABLE DATA; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -2304,7 +2404,7 @@ COPY public.custom_filters (id, account_id, expires_at, phrase, context, irrever
|
|||
-- Data for Name: domain_blocks; Type: TABLE DATA; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
COPY public.domain_blocks (id, domain, created_at, updated_at, severity, reject_media) FROM stdin;
|
||||
COPY public.domain_blocks (id, domain, created_at, updated_at, severity, reject_media, reject_reports) FROM stdin;
|
||||
\.
|
||||
|
||||
|
||||
|
@ -2397,7 +2497,7 @@ COPY public.media_attachments (id, status_id, file_file_name, file_content_type,
|
|||
-- Data for Name: mentions; Type: TABLE DATA; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
COPY public.mentions (id, status_id, created_at, updated_at, account_id) FROM stdin;
|
||||
COPY public.mentions (id, status_id, created_at, updated_at, account_id, silent) FROM stdin;
|
||||
\.
|
||||
|
||||
|
||||
|
@ -2455,6 +2555,14 @@ COPY public.oauth_applications (id, name, uid, secret, redirect_uri, scopes, cre
|
|||
\.
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: pghero_space_stats; Type: TABLE DATA; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
COPY public.pghero_space_stats (id, database, schema, relation, size, captured_at) FROM stdin;
|
||||
\.
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: preview_cards; Type: TABLE DATA; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -2678,6 +2786,13 @@ COPY public.schema_migrations (version) FROM stdin;
|
|||
20180813113448
|
||||
20180814171349
|
||||
20180820232245
|
||||
20180929222014
|
||||
20181007025445
|
||||
20181010141500
|
||||
20181017170937
|
||||
20181018205649
|
||||
20181024224956
|
||||
20181026034033
|
||||
\.
|
||||
|
||||
|
||||
|
@ -2805,6 +2920,13 @@ COPY public.web_settings (id, data, created_at, updated_at, user_id) FROM stdin;
|
|||
\.
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_conversations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
SELECT pg_catalog.setval('public.account_conversations_id_seq', 1, false);
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_domain_blocks_id_seq; Type: SEQUENCE SET; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -3001,6 +3123,13 @@ SELECT pg_catalog.setval('public.oauth_access_tokens_id_seq', 9, true);
|
|||
SELECT pg_catalog.setval('public.oauth_applications_id_seq', 1, true);
|
||||
|
||||
|
||||
--
|
||||
-- Name: pghero_space_stats_id_seq; Type: SEQUENCE SET; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
SELECT pg_catalog.setval('public.pghero_space_stats_id_seq', 1, false);
|
||||
|
||||
|
||||
--
|
||||
-- Name: preview_cards_id_seq; Type: SEQUENCE SET; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -3113,6 +3242,14 @@ SELECT pg_catalog.setval('public.web_push_subscriptions_id_seq', 1, false);
|
|||
SELECT pg_catalog.setval('public.web_settings_id_seq', 4, true);
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_conversations account_conversations_pkey; Type: CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.account_conversations
|
||||
ADD CONSTRAINT account_conversations_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_domain_blocks account_domain_blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -3345,6 +3482,14 @@ ALTER TABLE ONLY public.oauth_applications
|
|||
ADD CONSTRAINT oauth_applications_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: pghero_space_stats pghero_space_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.pghero_space_stats
|
||||
ADD CONSTRAINT pghero_space_stats_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: preview_cards preview_cards_pkey; Type: CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -3495,6 +3640,20 @@ CREATE UNIQUE INDEX account_activity ON public.notifications USING btree (accoun
|
|||
CREATE INDEX hashtag_search_index ON public.tags USING btree (lower((name)::text) text_pattern_ops);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_account_conversations_on_account_id; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE INDEX index_account_conversations_on_account_id ON public.account_conversations USING btree (account_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_account_conversations_on_conversation_id; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE INDEX index_account_conversations_on_conversation_id ON public.account_conversations USING btree (conversation_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_account_domain_blocks_on_account_id_and_domain; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -3845,6 +4004,13 @@ CREATE INDEX index_oauth_applications_on_owner_id_and_owner_type ON public.oauth
|
|||
CREATE UNIQUE INDEX index_oauth_applications_on_uid ON public.oauth_applications USING btree (uid);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_pghero_space_stats_on_database_and_captured_at; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE INDEX index_pghero_space_stats_on_database_and_captured_at ON public.pghero_space_stats USING btree (database, captured_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_preview_cards_on_url; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -4013,6 +4179,13 @@ CREATE UNIQUE INDEX index_subscriptions_on_account_id_and_callback_url ON public
|
|||
CREATE UNIQUE INDEX index_tags_on_name ON public.tags USING btree (name);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_unique_conversations; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_unique_conversations ON public.account_conversations USING btree (account_id, conversation_id, participant_account_ids);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_users_on_account_id; Type: INDEX; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -4357,6 +4530,14 @@ ALTER TABLE ONLY public.backups
|
|||
ADD CONSTRAINT fk_rails_096669d221 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_conversations fk_rails_1491654f9f; Type: FK CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.account_conversations
|
||||
ADD CONSTRAINT fk_rails_1491654f9f FOREIGN KEY (conversation_id) REFERENCES public.conversations(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: accounts fk_rails_2320833084; Type: FK CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
@ -4453,6 +4634,14 @@ ALTER TABLE ONLY public.status_pins
|
|||
ADD CONSTRAINT fk_rails_65c05552f1 FOREIGN KEY (status_id) REFERENCES public.statuses(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: account_conversations fk_rails_6f5278b6e9; Type: FK CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.account_conversations
|
||||
ADD CONSTRAINT fk_rails_6f5278b6e9 FOREIGN KEY (account_id) REFERENCES public.accounts(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: web_push_subscriptions fk_rails_751a9f390b; Type: FK CONSTRAINT; Schema: public; Owner: pinafore
|
||||
--
|
||||
|
|
Binary file not shown.
|
@ -44,3 +44,12 @@ export function concat () {
|
|||
}
|
||||
return res
|
||||
}
|
||||
|
||||
export function indexWhere (arr, cb) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (cb(arr[i], i)) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
|
|
@ -4,10 +4,8 @@ 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" },
|
||||
|
|
|
@ -22,7 +22,7 @@ test('Shows the home timeline', async t => {
|
|||
|
||||
await validateTimeline(t, homeTimeline)
|
||||
|
||||
await t.expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql('49')
|
||||
await t.expect(getFirstVisibleStatus().getAttribute('aria-setsize')).eql('47')
|
||||
})
|
||||
|
||||
test('Shows notifications', async t => {
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Selector as $ } from 'testcafe'
|
|||
fixture`005-status-types.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('shows direct vs followers-only vs regular', async t => {
|
||||
test('shows followers-only vs regular in home timeline', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.expect(getNthStatus(1).getAttribute('aria-label')).eql('Status by admin')
|
||||
|
@ -18,11 +18,6 @@ test('shows direct vs followers-only vs regular', async t => {
|
|||
.expect($(`${getNthStatusSelector(2)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label'))
|
||||
.eql('Cannot be boosted because this is followers-only')
|
||||
.expect($(`${getNthStatusSelector(2)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).ok()
|
||||
.expect(getNthStatus(3).getAttribute('aria-label')).eql('Direct message by admin')
|
||||
.expect($(`${getNthStatusSelector(3)} .status-content`).innerText).contains('notification of direct message')
|
||||
.expect($(`${getNthStatusSelector(3)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label'))
|
||||
.eql('Cannot be boosted because this is a direct message')
|
||||
.expect($(`${getNthStatusSelector(3)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).ok()
|
||||
})
|
||||
|
||||
test('shows direct vs followers-only vs regular in notifications', async t => {
|
||||
|
|
|
@ -1,34 +1,44 @@
|
|||
import { closeDialogButton, getNthStatus, getNthStatusSelector, modalDialogContents, scrollToStatus } from '../utils'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
import { Selector as $ } from 'testcafe'
|
||||
import { homeTimeline } from '../fixtures'
|
||||
import { indexWhere } from '../../routes/_utils/arrays'
|
||||
|
||||
fixture`008-status-media.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('shows sensitive images and videos', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await scrollToStatus(t, 7)
|
||||
await t.expect($(`${getNthStatusSelector(7)} .status-media img`).exists).notOk()
|
||||
.click($(`${getNthStatusSelector(7)} .status-sensitive-media-button`))
|
||||
.expect($(`${getNthStatusSelector(7)} .status-media img`).getAttribute('alt')).eql('kitten')
|
||||
.expect($(`${getNthStatusSelector(7)} .status-media img`).hasAttribute('src')).ok()
|
||||
.hover(getNthStatus(8))
|
||||
.expect($(`${getNthStatusSelector(8)} .status-media .play-video-button`).exists).notOk()
|
||||
.click($(`${getNthStatusSelector(8)} .status-sensitive-media-button`))
|
||||
.expect($(`${getNthStatusSelector(8)} .status-media .play-video-button`).exists).ok()
|
||||
|
||||
let kittenIdx = indexWhere(homeTimeline, _ => _.spoiler === 'kitten CW')
|
||||
let videoIdx = indexWhere(homeTimeline, _ => _.content === 'secret video')
|
||||
|
||||
await scrollToStatus(t, kittenIdx)
|
||||
await t.expect($(`${getNthStatusSelector(kittenIdx)} .status-media img`).exists).notOk()
|
||||
.click($(`${getNthStatusSelector(kittenIdx)} .status-sensitive-media-button`))
|
||||
.expect($(`${getNthStatusSelector(kittenIdx)} .status-media img`).getAttribute('alt')).eql('kitten')
|
||||
.expect($(`${getNthStatusSelector(kittenIdx)} .status-media img`).hasAttribute('src')).ok()
|
||||
.hover(getNthStatus(videoIdx))
|
||||
.expect($(`${getNthStatusSelector(videoIdx)} .status-media .play-video-button`).exists).notOk()
|
||||
.click($(`${getNthStatusSelector(videoIdx)} .status-sensitive-media-button`))
|
||||
.expect($(`${getNthStatusSelector(videoIdx)} .status-media .play-video-button`).exists).ok()
|
||||
})
|
||||
|
||||
test('click and close image and video modals', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await scrollToStatus(t, 9)
|
||||
|
||||
let videoIdx = indexWhere(homeTimeline, _ => _.content === "here's a video")
|
||||
let kittenIdx = indexWhere(homeTimeline, _ => _.content === "here's an animated kitten gif")
|
||||
|
||||
await scrollToStatus(t, videoIdx)
|
||||
await t.expect(modalDialogContents.exists).notOk()
|
||||
.click($(`${getNthStatusSelector(9)} .play-video-button`))
|
||||
.click($(`${getNthStatusSelector(videoIdx)} .play-video-button`))
|
||||
.expect(modalDialogContents.exists).ok()
|
||||
.click(closeDialogButton)
|
||||
.expect(modalDialogContents.exists).notOk()
|
||||
.hover(getNthStatus(11))
|
||||
.hover(getNthStatus(12))
|
||||
.click($(`${getNthStatusSelector(12)} .show-image-button`))
|
||||
.hover(getNthStatus(kittenIdx - 1))
|
||||
.hover(getNthStatus(kittenIdx))
|
||||
.click($(`${getNthStatusSelector(kittenIdx)} .show-image-button`))
|
||||
.expect(modalDialogContents.exists).ok()
|
||||
.click(closeDialogButton)
|
||||
.expect(modalDialogContents.exists).notOk()
|
||||
|
|
|
@ -5,21 +5,26 @@ import {
|
|||
} from '../utils'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
import { Selector as $ } from 'testcafe'
|
||||
import { indexWhere } from '../../routes/_utils/arrays'
|
||||
import { homeTimeline } from '../fixtures'
|
||||
|
||||
fixture`010-focus.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('modal preserves focus', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await scrollToStatus(t, 9)
|
||||
|
||||
let idx = indexWhere(homeTimeline, _ => _.content === "here's a video")
|
||||
|
||||
await scrollToStatus(t, idx)
|
||||
// explicitly hover-focus-click
|
||||
await t.hover($(`${getNthStatusSelector(9)} .play-video-button`))
|
||||
await focus(`${getNthStatusSelector(9)} .play-video-button`)()
|
||||
await t.click($(`${getNthStatusSelector(9)} .play-video-button`))
|
||||
await t.hover($(`${getNthStatusSelector(idx)} .play-video-button`))
|
||||
await focus(`${getNthStatusSelector(idx)} .play-video-button`)()
|
||||
await t.click($(`${getNthStatusSelector(idx)} .play-video-button`))
|
||||
.click(closeDialogButton)
|
||||
.expect(modalDialogContents.exists).notOk()
|
||||
.expect(getActiveElementClass()).contains('play-video-button')
|
||||
.expect(getActiveElementInsideNthStatus()).eql('9')
|
||||
.expect(getActiveElementInsideNthStatus()).eql(idx.toString())
|
||||
})
|
||||
|
||||
test('timeline preserves focus', async t => {
|
||||
|
|
|
@ -6,6 +6,8 @@ import {
|
|||
getNthStatus, getUrl, homeNavButton, notificationsNavButton, scrollToStatus
|
||||
} from '../utils'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
import { homeTimeline } from '../fixtures'
|
||||
import { indexWhere } from '../../routes/_utils/arrays'
|
||||
|
||||
fixture`017-compose-reply.js`
|
||||
.page`http://localhost:4002`
|
||||
|
@ -52,48 +54,46 @@ test('replies have same privacy as replied-to status by default', async t => {
|
|||
.expect(getNthPostPrivacyButton(2).getAttribute('aria-label')).eql('Adjust privacy (currently Followers-only)')
|
||||
.click(getNthReplyButton(2))
|
||||
.hover(getNthStatus(3))
|
||||
.click(getNthReplyButton(3))
|
||||
.expect(getNthPostPrivacyButton(3).getAttribute('aria-label')).eql('Adjust privacy (currently Direct)')
|
||||
.click(getNthReplyButton(3))
|
||||
.hover(getNthStatus(4))
|
||||
.hover(getNthStatus(5))
|
||||
.hover(getNthStatus(6))
|
||||
.hover(getNthStatus(7))
|
||||
.click(getNthReplyButton(7))
|
||||
.expect(getNthPostPrivacyButton(7).getAttribute('aria-label')).eql('Adjust privacy (currently Public)')
|
||||
.click(getNthReplyButton(7))
|
||||
.click(getNthReplyButton(5))
|
||||
.expect(getNthPostPrivacyButton(5).getAttribute('aria-label')).eql('Adjust privacy (currently Public)')
|
||||
.click(getNthReplyButton(5))
|
||||
})
|
||||
|
||||
test('replies have same CW as replied-to status', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await scrollToStatus(t, 7)
|
||||
await t.click(getNthReplyButton(7))
|
||||
.expect(getNthReplyContentWarningInput(7).value).eql('kitten CW')
|
||||
.click(getNthStatus(7))
|
||||
let kittenIdx = indexWhere(homeTimeline, _ => _.spoiler === 'kitten CW')
|
||||
await scrollToStatus(t, kittenIdx)
|
||||
await t.click(getNthReplyButton(kittenIdx))
|
||||
.expect(getNthReplyContentWarningInput(kittenIdx).value).eql('kitten CW')
|
||||
.click(getNthStatus(kittenIdx))
|
||||
.click(getNthReplyButton(0))
|
||||
.expect(getNthReplyContentWarningInput(0).value).eql('kitten CW')
|
||||
})
|
||||
|
||||
test('replies save deletions of CW', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await scrollToStatus(t, 7)
|
||||
await t.click(getNthReplyButton(7))
|
||||
.expect(getNthReplyContentWarningInput(7).value).eql('kitten CW')
|
||||
.click(getNthReplyContentWarningButton(7))
|
||||
.expect(getNthReplyContentWarningInput(7).exists).notOk()
|
||||
.click(getNthStatus(7))
|
||||
let kittenIdx = indexWhere(homeTimeline, _ => _.spoiler === 'kitten CW')
|
||||
await scrollToStatus(t, kittenIdx)
|
||||
await t.click(getNthReplyButton(kittenIdx))
|
||||
.expect(getNthReplyContentWarningInput(kittenIdx).value).eql('kitten CW')
|
||||
.click(getNthReplyContentWarningButton(kittenIdx))
|
||||
.expect(getNthReplyContentWarningInput(kittenIdx).exists).notOk()
|
||||
.click(getNthStatus(kittenIdx))
|
||||
.click(getNthReplyButton(0))
|
||||
.expect(getNthReplyContentWarningInput(0).exists).notOk()
|
||||
})
|
||||
|
||||
test('replies save changes to CW', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await scrollToStatus(t, 7)
|
||||
await t.click(getNthReplyButton(7))
|
||||
.expect(getNthReplyContentWarningInput(7).value).eql('kitten CW')
|
||||
.typeText(getNthReplyContentWarningInput(7), ' yolo', { paste: true })
|
||||
.expect(getNthReplyContentWarningInput(7).value).eql('kitten CW yolo')
|
||||
.click(getNthStatus(7))
|
||||
let kittenIdx = indexWhere(homeTimeline, _ => _.spoiler === 'kitten CW')
|
||||
await scrollToStatus(t, kittenIdx)
|
||||
await t.click(getNthReplyButton(kittenIdx))
|
||||
.expect(getNthReplyContentWarningInput(kittenIdx).value).eql('kitten CW')
|
||||
.typeText(getNthReplyContentWarningInput(kittenIdx), ' yolo', { paste: true })
|
||||
.expect(getNthReplyContentWarningInput(kittenIdx).value).eql('kitten CW yolo')
|
||||
.click(getNthStatus(kittenIdx))
|
||||
.click(getNthReplyButton(0))
|
||||
.expect(getNthReplyContentWarningInput(0).value).eql('kitten CW yolo')
|
||||
})
|
||||
|
|
|
@ -4,6 +4,8 @@ import {
|
|||
scrollToBottomOfTimeline, scrollToTopOfTimeline
|
||||
} from '../utils'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
import { indexWhere } from '../../routes/_utils/arrays'
|
||||
import { homeTimeline } from '../fixtures'
|
||||
|
||||
fixture`100-favorite-unfavorite.js`
|
||||
.page`http://localhost:4002`
|
||||
|
@ -59,20 +61,21 @@ test('unfavorites a status', async t => {
|
|||
|
||||
test('Keeps the correct favorites count', async t => {
|
||||
await loginAsFoobar(t)
|
||||
let idx = indexWhere(homeTimeline, _ => _.content === 'this is unlisted')
|
||||
await t
|
||||
.hover(getNthStatus(4))
|
||||
.click(getNthFavoriteButton(4))
|
||||
.expect(getNthFavorited(4)).eql('true')
|
||||
.click(getNthStatus(4))
|
||||
.hover(getNthStatus(idx))
|
||||
.click(getNthFavoriteButton(idx))
|
||||
.expect(getNthFavorited(idx)).eql('true')
|
||||
.click(getNthStatus(idx))
|
||||
.expect(getUrl()).contains('/status')
|
||||
.expect(getNthFavorited(0)).eql('true')
|
||||
.expect(getFavoritesCount()).eql(2)
|
||||
.click(homeNavButton)
|
||||
.expect(getUrl()).eql('http://localhost:4002/')
|
||||
.hover(getNthStatus(4))
|
||||
.click(getNthFavoriteButton(4))
|
||||
.expect(getNthFavorited(4)).eql('false')
|
||||
.click(getNthStatus(4))
|
||||
.hover(getNthStatus(idx))
|
||||
.click(getNthFavoriteButton(idx))
|
||||
.expect(getNthFavorited(idx)).eql('false')
|
||||
.click(getNthStatus(idx))
|
||||
.expect(getUrl()).contains('/status')
|
||||
.expect(getNthFavorited(0)).eql('false')
|
||||
.expect(getFavoritesCount()).eql(1)
|
||||
|
|
|
@ -37,44 +37,44 @@ test('reblogs a status', async t => {
|
|||
test('unreblogs a status', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.hover(getNthStatus(4))
|
||||
.expect(getNthReblogged(4)).eql('false')
|
||||
.click(getNthReblogButton(4))
|
||||
.expect(getNthReblogged(4)).eql('true')
|
||||
.click(getNthReblogButton(4))
|
||||
.expect(getNthReblogged(4)).eql('false')
|
||||
.hover(getNthStatus(3))
|
||||
.expect(getNthReblogged(3)).eql('false')
|
||||
.click(getNthReblogButton(3))
|
||||
.expect(getNthReblogged(3)).eql('true')
|
||||
.click(getNthReblogButton(3))
|
||||
.expect(getNthReblogged(3)).eql('false')
|
||||
|
||||
// scroll down and back up to force an unrender
|
||||
await scrollToBottomOfTimeline(t)
|
||||
await scrollToTopOfTimeline(t)
|
||||
await t
|
||||
.hover(getNthStatus(4))
|
||||
.expect(getNthReblogged(4)).eql('false')
|
||||
.hover(getNthStatus(3))
|
||||
.expect(getNthReblogged(3)).eql('false')
|
||||
.click(notificationsNavButton)
|
||||
.click(homeNavButton)
|
||||
.expect(getNthReblogged(4)).eql('false')
|
||||
.expect(getNthReblogged(3)).eql('false')
|
||||
.click(notificationsNavButton)
|
||||
.navigateTo('/')
|
||||
.expect(getNthReblogged(4)).eql('false')
|
||||
.click(getNthReblogButton(4))
|
||||
.expect(getNthReblogged(4)).eql('true')
|
||||
.expect(getNthReblogged(3)).eql('false')
|
||||
.click(getNthReblogButton(3))
|
||||
.expect(getNthReblogged(3)).eql('true')
|
||||
})
|
||||
|
||||
test('Keeps the correct reblogs count', async t => {
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.hover(getNthStatus(4))
|
||||
.expect(getNthReblogged(4)).eql('true')
|
||||
.click(getNthStatus(4))
|
||||
.hover(getNthStatus(3))
|
||||
.expect(getNthReblogged(3)).eql('true')
|
||||
.click(getNthStatus(3))
|
||||
.expect(getUrl()).contains('/status')
|
||||
.expect(getNthReblogged(0)).eql('true')
|
||||
.expect(getReblogsCount()).eql(2)
|
||||
.click(homeNavButton)
|
||||
.expect(getUrl()).eql('http://localhost:4002/')
|
||||
.hover(getNthStatus(4))
|
||||
.click(getNthReblogButton(4))
|
||||
.expect(getNthReblogged(4)).eql('false')
|
||||
.click(getNthStatus(4))
|
||||
.hover(getNthStatus(3))
|
||||
.click(getNthReblogButton(3))
|
||||
.expect(getNthReblogged(3)).eql('false')
|
||||
.click(getNthStatus(3))
|
||||
.expect(getUrl()).contains('/status')
|
||||
.expect(getNthReblogged(0)).eql('false')
|
||||
.expect(getReblogsCount()).eql(1)
|
||||
|
|
|
@ -1,37 +1,25 @@
|
|||
import { loginAsFoobar } from '../roles'
|
||||
import {
|
||||
getNthStatus, getNthStatusSelector, getUrl, homeNavButton, notificationsNavButton,
|
||||
validateTimeline
|
||||
getNthStatus, getUrl, homeNavButton, notificationsNavButton
|
||||
} from '../utils'
|
||||
import { favoriteStatusAs } from '../serverActions'
|
||||
import { notifications } from '../fixtures'
|
||||
import { Selector as $ } from 'testcafe'
|
||||
import { favoriteStatusAs, postAs } from '../serverActions'
|
||||
|
||||
fixture`102-notifications.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('shows unread notifications', async t => {
|
||||
let { id } = await postAs('foobar', 'somebody please favorite this to validate me')
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.hover(getNthStatus(0))
|
||||
.hover(getNthStatus(2))
|
||||
.hover(getNthStatus(4))
|
||||
.hover(getNthStatus(5))
|
||||
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications')
|
||||
let statusId = (await $(`${getNthStatusSelector(5)} .status-relative-date`).getAttribute('href'))
|
||||
.split('/').slice(-1)[0]
|
||||
await favoriteStatusAs('admin', statusId)
|
||||
await favoriteStatusAs('admin', id)
|
||||
await t
|
||||
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (1)')
|
||||
.click(notificationsNavButton)
|
||||
.expect(getUrl()).contains('/notifications')
|
||||
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (current page)')
|
||||
await validateTimeline(t, [
|
||||
{
|
||||
favoritedBy: 'admin',
|
||||
content: 'this is followers-only'
|
||||
}
|
||||
].concat(notifications))
|
||||
.expect(getNthStatus(0).innerText).contains('somebody please favorite this to validate me')
|
||||
.expect(getNthStatus(0).innerText).match(/admin\s+favorited your status/)
|
||||
await t
|
||||
.click(homeNavButton)
|
||||
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications')
|
||||
|
|
Loading…
Reference in New Issue