import { Given, When, Then } from "cypress-cucumber-preprocessor/steps"; import helpers from "../../support/helpers"; import { VERSION } from '../../constants/terms-and-conditions-version.js' import locales from '../../../webapp/locales' import orderBy from 'lodash/orderBy' /* global cy */ const languages = orderBy(locales, 'name') let lastPost = {}; let loginCredentials = { email: "peterpan@example.org", password: "1234" }; const termsAndConditionsAgreedVersion = { termsAndConditionsAgreedVersion: VERSION }; const narratorParams = { id: 'id-of-peter-pan', name: "Peter Pan", slug: "peter-pan", avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/nerrsoft/128.jpg", ...loginCredentials, ...termsAndConditionsAgreedVersion, }; const annoyingParams = { email: "spammy-spammer@example.org", password: "1234", ...termsAndConditionsAgreedVersion }; Given("I am logged in", () => { cy.login(loginCredentials); }); Given("I am logged in as the muted user", () => { cy.login({ email: annoyingParams.email, password: '1234' }); }); Given("we have a selection of categories", () => { cy.createCategories("cat0", "just-for-fun"); }); Given("we have a selection of tags and categories as well as posts", () => { cy.createCategories("cat12") .factory() .create("Tag", { id: "Ecology" }) .create("Tag", { id: "Nature" }) .create("Tag", { id: "Democracy" }); cy.factory() .create("User", { id: 'a1' }) .create("Post", { authorId: 'a1', tagIds: ["Ecology", "Nature", "Democracy"], categoryIds: ["cat12"] }) .create("Post", { authorId: 'a1', tagIds: ["Nature", "Democracy"], categoryIds: ["cat121"] }); cy.factory() .create("User", { id: 'a2' }) .create("Post", { authorId: 'a2', tagIds: ['Nature', 'Democracy'], categoryIds: ["cat12"] }); cy.factory() .create("Post", { authorId: narratorParams.id, tagIds: ['Democracy'], categoryIds: ["cat122"] }) }); Given("we have the following user accounts:", table => { table.hashes().forEach(params => { cy.factory().create("User", { ...params, ...termsAndConditionsAgreedVersion }); }); }); Given("I have a user account", () => { cy.factory().create("User", narratorParams); }); Given("my user account has the role {string}", role => { cy.factory().create("User", { role, ...loginCredentials, ...termsAndConditionsAgreedVersion, }); }); When("I log out", cy.logout); When("I visit {string}", page => { cy.openPage(page); }); When("I visit the {string} page", page => { cy.openPage(page); }); Given("I am on the {string} page", page => { cy.openPage(page); }); When("I fill in my email and password combination and click submit", () => { cy.login(loginCredentials); }); When(/(?:when )?I refresh the page/, () => { cy.reload(); }); When("I log out through the menu in the top right corner", () => { cy.get(".avatar-menu").click(); cy.get(".avatar-menu-popover") .find('a[href="/logout"]') .click(); }); Then("I can see my name {string} in the dropdown menu", () => { cy.get(".avatar-menu-popover").should("contain", narratorParams.name); }); Then("I see the login screen again", () => { cy.location("pathname").should("contain", "/login"); }); Then("I can click on my profile picture in the top right corner", () => { cy.get(".avatar-menu").click(); cy.get(".avatar-menu-popover"); }); Then("I am still logged in", () => { cy.get(".avatar-menu").click(); cy.get(".avatar-menu-popover").contains(narratorParams.name); }); When("I select {string} in the language menu", name => { cy.switchLanguage(name, true); }); Given("I previously switched the language to {string}", name => { cy.switchLanguage(name, true); }); Then("the whole user interface appears in {string}", name => { const { code } = helpers.getLangByName(name); cy.get(`html[lang=${code}]`); cy.getCookie("locale").should("have.property", "value", code); }); Then("I see a button with the label {string}", label => { cy.contains("button", label); }); When(`I click on {string}`, linkOrButton => { cy.contains(linkOrButton).click(); }); When(`I click on the menu item {string}`, linkOrButton => { cy.contains(".ds-menu-item", linkOrButton).click(); }); When("I press {string}", label => { cy.contains(label).click(); }); Given("we have this user in our database:", table => { const [firstRow] = table.hashes() cy.factory().create('User', firstRow) }) Given("we have the following posts in our database:", table => { cy.factory().create('Category', { id: `cat-456`, name: "Just For Fun", slug: `just-for-fun`, icon: "smile" }) table.hashes().forEach(({ ...postAttributes }, i) => { postAttributes = { ...postAttributes, deleted: Boolean(postAttributes.deleted), disabled: Boolean(postAttributes.disabled), categoryIds: ['cat-456'] } cy.factory().create("Post", postAttributes); }) }); Then("I see a success message:", message => { cy.contains(message); }); When("I click on the avatar menu in the top right corner", () => { cy.get(".avatar-menu").click(); }); When( "I click on the big plus icon in the bottom right corner to create post", () => { cy.get(".post-add-button").click(); } ); Given("I previously created a post", () => { lastPost.authorId = narratorParams.id lastPost.title = "previously created post"; lastPost.content = "with some content"; cy.factory() .create("Post", lastPost); }); When("I choose {string} as the title of the post", title => { lastPost.title = title.replace("\n", " "); cy.get('input[name="title"]').type(lastPost.title); }); When("I type in the following text:", text => { lastPost.content = text.replace("\n", " "); cy.get(".editor .ProseMirror").type(lastPost.content); }); Then("I select a category", () => { cy.get(".base-button") .contains("Just for Fun") .click(); }); When("I choose {string} as the language for the post", (languageCode) => { cy.get('.ds-flex-item > .ds-form-item .ds-select ') .click().get('.ds-select-option') .eq(languages.findIndex(l => l.code === languageCode)).click() }) Then("the post shows up on the landing page at position {int}", index => { cy.openPage("landing"); const selector = `.post-card:nth-child(${index}) > .ds-card-content`; cy.get(selector).should("contain", lastPost.title); cy.get(selector).should("contain", lastPost.content); }); Then("I get redirected to {string}", route => { cy.location("pathname").should("contain", route.replace("...", "")); }); Then("the post was saved successfully", () => { cy.get(".ds-card-content > .ds-heading").should("contain", lastPost.title); cy.get(".content").should("contain", lastPost.content); }); Then(/^I should see only ([0-9]+) posts? on the landing page/, postCount => { cy.get(".post-card").should("have.length", postCount); }); Then("the first post on the landing page has the title:", title => { cy.get(".post-card:first").should("contain", title); }); Then( "the page {string} returns a 404 error with a message:", (route, message) => { cy.request({ url: route, failOnStatusCode: false }) .its("status") .should("eq", 404); cy.visit(route, { failOnStatusCode: false }); cy.get(".error").should("contain", message); } ); Given("my user account has the following login credentials:", table => { loginCredentials = table.hashes()[0]; cy.debug(); cy.factory().create("User", { ...termsAndConditionsAgreedVersion, ...loginCredentials }); }); When("I fill the password form with:", table => { table = table.rowsHash(); cy.get("input[id=oldPassword]") .type(table["Your old password"]) .get("input[id=password]") .type(table["Your new passsword"]) .get("input[id=passwordConfirmation]") .type(table["Confirm new password"]); }); When("submit the form", () => { cy.get("form").submit(); }); Then("I cannot login anymore with password {string}", password => { cy.reload(); const { email } = loginCredentials; cy.visit(`/login`); cy.get("input[name=email]") .trigger("focus") .type(email); cy.get("input[name=password]") .trigger("focus") .type(password); cy.get("button[name=submit]") .as("submitButton") .click(); cy.get(".iziToast-wrapper").should( "contain", "Incorrect email address or password." ); }); Then("I can login successfully with password {string}", password => { cy.reload(); cy.login({ ...loginCredentials, ...{ password } }); cy.get(".iziToast-wrapper").should("contain", "You are logged in!"); }); When("I log in with the following credentials:", table => { const { email, password } = table.hashes()[0]; cy.login({ email, password }); }); When("open the notification menu and click on the first item", () => { cy.get(".notifications-menu").invoke('show').click(); // "invoke('show')" because of the delay for show the menu cy.get(".notification-mention-post") .first() .click({ force: true }); }); Then("see {int} unread notifications in the top menu", count => { cy.get(".notifications-menu").should("contain", count); }); Then("I get to the post page of {string}", path => { path = path.replace("...", ""); cy.url().should("contain", "/post/"); cy.url().should("contain", path); }); When( "I start to write a new post with the title {string} beginning with:", (title, intro) => { cy.get(".post-add-button").click(); cy.get('input[name="title"]').type(title); cy.get(".ProseMirror").type(intro); } ); When("mention {string} in the text", mention => { cy.get(".ProseMirror").type(" @"); cy.get(".suggestion-list__item") .contains(mention) .click(); cy.debug(); }); Then("the notification gets marked as read", () => { cy.get(".notifications-menu-popover .notification") .first() .should("have.class", "read"); }); Then("there are no notifications in the top menu", () => { cy.get(".notifications-menu").should("contain", "0"); }); Given("there is an annoying user called {string}", name => { cy.factory().create("User", { ...annoyingParams, id: "annoying-user", name, ...termsAndConditionsAgreedVersion, }); }); Given("there is an annoying user who has muted me", () => { cy.neode() .first("User", { role: 'moderator' }) .then(mutedUser => { cy.neode() .first("User", { id: 'annoying-user' }) .relateTo(mutedUser, "muted"); }); }); Given("I am on the profile page of the annoying user", name => { cy.openPage("/profile/annoying-user/spammy-spammer"); }); When("I visit the profile page of the annoying user", name => { cy.openPage("/profile/annoying-user"); }); When("I ", name => { cy.openPage("/profile/annoying-user"); }); When( "I click on {string} from the content menu in the user info box", button => { cy.get(".user-content-menu .base-button").click(); cy.get(".popover .ds-menu-item-link") .contains(button) .click({ force: true }); } ); When("I navigate to my {string} settings page", settingsPage => { cy.get(".avatar-menu").click(); cy.get(".avatar-menu-popover") .find("a[href]") .contains("Settings") .click(); cy.contains(".ds-menu-item-link", settingsPage).click(); }); Given("I follow the user {string}", name => { cy.neode() .first("User", { name }) .then(followed => { cy.neode() .first("User", { name: narratorParams.name }) .relateTo(followed, "following"); }); }); Given('"Spammy Spammer" wrote a post {string}', title => { cy.createCategories("cat21") .factory() .create("Post", { authorId: 'annoying-user', title, categoryIds: ["cat21"] }); }); Then("the list of posts of this user is empty", () => { cy.get(".ds-card-content").not(".post-link"); cy.get(".main-container").find(".ds-space.hc-empty"); }); Then("nobody is following the user profile anymore", () => { cy.get(".ds-card-content").not(".post-link"); cy.get(".main-container").contains( ".ds-card-content", "is not followed by anyone" ); }); Given("I wrote a post {string}", title => { cy.createCategories(`cat213`, title) .factory() .create("Post", { authorId: narratorParams.id, title, categoryIds: ["cat213"] }); }); When("I mute the user {string}", name => { cy.neode() .first("User", { name }) .then(mutedUser => { cy.neode() .first("User", { name: narratorParams.name }) .relateTo(mutedUser, "muted"); }); }); When("I log in with:", table => { const [firstRow] = table.hashes(); const { Email, Password } = firstRow; cy.login({ email: Email, password: Password }); }); Then("I see only one post with the title {string}", title => { cy.get(".main-container") .find(".post-link") .should("have.length", 1); cy.get(".main-container").contains(".post-link", title); });