Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:

HASHNODE_API_URL: api_url_from_hashnode_dashboard
ENGLISH_HASHNODE_HOST: host_from_hashnode_dashboard
CHINESE_HASHNODE_HOST: host_from_hashnode_dashboard
ESPANOL_HASHNODE_HOST: host_from_hashnode_dashboard

ADS_ENABLED: true
GOOGLE_ADSENSE_DATA_AD_CLIENT: ca-pub-1234567890
Expand Down
8 changes: 7 additions & 1 deletion config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ const algoliaIndices = {
ukrainian: 'news-uk'
};

/* These locales are on the same headless Hashnode instance,
* and require special filtering when fetching from Hashnode.
*/
const sharedHostLocales = ['italian', 'japanese', 'korean', 'ukrainian'];

const {
LOCALE_FOR_UI: localeForUI,
LOCALE_FOR_GHOST: localeForGhost,
Expand Down Expand Up @@ -159,5 +164,6 @@ export const config = {
!chatWebhookToken ||
chatWebhookToken === 'chat_webhook_token_from_space_settings'
? ''
: chatWebhookToken
: chatWebhookToken,
sharedHostLocales
};
280 changes: 185 additions & 95 deletions cypress/e2e/espanol/author/author.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,165 +26,255 @@
x: {
link: "[data-test-label='x-link']",
icon: "[data-test-label='x-icon']"
},
github: {
link: "[data-test-label='github-link']",
icon: "[data-test-label='github-icon']"
}
}
};

describe('Author page (Ghost sourced)', () => {
describe('Author page', () => {
before(() => {
// Update baseUrl to include current language
Cypress.config('baseUrl', 'http://localhost:8080/espanol/news/');
});

context('Author with profile image', () => {
beforeEach(() => {
cy.visit('/author/rafael/');
});
context('Ghost sourced', () => {
context('Author with profile image', () => {
beforeEach(() => {
cy.visit('/author/rafael/');
});

it('should render', () => {
cy.contains(selectors.authorName, 'Rafael D. Hernandez');
});
it('should render', () => {
cy.contains(selectors.authorName, 'Rafael D. Hernandez');
});

it("should show the author's profile image", () => {
cy.get(selectors.authorProfileImage).then($el =>
expect($el[0].tagName.toLowerCase()).to.equal('img')
);
});
it("should show the author's profile image", () => {
cy.get(selectors.authorProfileImage).then($el =>
expect($el[0].tagName.toLowerCase()).to.equal('img')
);
});

it("the author profile image should contain an `alt` attribute with the author's name", () => {
cy.get<HTMLImageElement>(selectors.authorProfileImage).then($el =>
expect($el[0].alt).to.equal('Rafael D. Hernandez')
);
});
it("the author profile image should contain an `alt` attribute with the author's name", () => {
cy.get<HTMLImageElement>(selectors.authorProfileImage).then($el =>
expect($el[0].alt).to.equal('Rafael D. Hernandez')
);
});

it("should show the author's location and post count on larger screens", () => {
cy.get(selectors.authorLocation).should('be.visible');
cy.get(selectors.authorPostCount).should('be.visible');
});
it("should show the author's location and post count on larger screens", () => {
cy.get(selectors.authorLocation).should('be.visible');
cy.get(selectors.authorPostCount).should('be.visible');
});

it(`should show 18 posts on load`, () => {
getPostCards().should('have.length', 18);
});
it(`should show 18 posts on load`, () => {
getPostCards().should('have.length', 18);
});

it('should show the correct number of total posts', () => {
loadAndCountAllPostCards(selectors.authorPostCount);
it('should show the correct number of total posts', () => {
loadAndCountAllPostCards(selectors.authorPostCount);
});
});
});

context('Author with no profile image', () => {
beforeEach(() => {
cy.visit('/author/mrugesh/');
});
context('Author with no profile image', () => {
beforeEach(() => {
cy.visit('/author/mrugesh/');
});

it('should render', () => {
cy.contains(selectors.authorName, 'Mrugesh Mohapatra');
});
it('should render', () => {
cy.contains(selectors.authorName, 'Mrugesh Mohapatra');
});

it('should show the avatar SVG', () => {
cy.get(selectors.avatar).then($el =>
expect($el[0].tagName.toLowerCase()).to.equal('svg')
);
});
it('should show the avatar SVG', () => {
cy.get(selectors.avatar).then($el =>
expect($el[0].tagName.toLowerCase()).to.equal('svg')
);
});

it("the avatar SVG should contain a `title` element with the author's name", () => {
cy.get(selectors.avatar).contains('title', 'Mrugesh Mohapatra');
it("the avatar SVG should contain a `title` element with the author's name", () => {
cy.get(selectors.avatar).contains('title', 'Mrugesh Mohapatra');
});
});
});

context('Social media', () => {
// Note: Ghost only supports links to Facebook, Twitter, and websites
context('Facebook', () => {
context('An author with no Facebook profile link', () => {
before(() => {
cy.visit('/author/rafael/');
});
context('Social media', () => {
// Note: Ghost only supports links to Facebook, Twitter, and websites
context('Facebook', () => {
context('An author with no Facebook profile link', () => {
before(() => {
cy.visit('/author/rafael/');
});

it('should not show an X link and icon', () => {
cy.get(selectors.socialMedia.facebook.link).should('not.exist');
cy.get(selectors.socialMedia.facebook.icon).should('not.exist');
it('should not show an X link and icon', () => {
cy.get(selectors.socialMedia.facebook.link).should('not.exist');
cy.get(selectors.socialMedia.facebook.icon).should('not.exist');
});
});
});

context('An author with a Facebook profile link', () => {
before(() => {
cy.visit('/author/freecodecamp/');
});
context('An author with a Facebook profile link', () => {
before(() => {
cy.visit('/author/freecodecamp/');
});

it('should show a Facebook link and icon', () => {
cy.get(selectors.socialMedia.facebook.link)
.should(
'have.attr',
'href',
'https://www.facebook.com/freecodecamp'
)
.find('svg')
.should('have.attr', 'data-test-label', 'facebook-icon');
it('should show a Facebook link and icon', () => {
cy.get(selectors.socialMedia.facebook.link)
.should(
'have.attr',
'href',
'https://www.facebook.com/freecodecamp'
)
.find('svg')
.should('have.attr', 'data-test-label', 'facebook-icon');
});
});
});
});

context('Twitter', () => {
context('Author with no Twitter profile link', () => {
before(() => {
cy.visit('/author/mrugesh/');
});
context('Twitter', () => {
context('Author with no Twitter profile link', () => {
before(() => {
cy.visit('/author/mrugesh/');
});

it('should not show an X link and icon', () => {
cy.get(selectors.socialMedia.x.link).should('not.exist');
cy.get(selectors.socialMedia.x.icon).should('not.exist');
it('should not show an X link and icon', () => {
cy.get(selectors.socialMedia.x.link).should('not.exist');
cy.get(selectors.socialMedia.x.icon).should('not.exist');
});
});
});

context('Author with a Twitter profile link', () => {
before(() => {
cy.visit('/author/rafael/');
context('Author with a Twitter profile link', () => {
before(() => {
cy.visit('/author/rafael/');
});

it('should show an X link and icon', () => {
cy.get(selectors.socialMedia.x.link)
.should('have.attr', 'href', 'https://x.com/RafaelDavisH')
.find('svg')
.should('have.attr', 'data-test-label', 'x-icon');
});
});

it('should show an X link and icon', () => {
cy.get(selectors.socialMedia.x.link)
.should('have.attr', 'href', 'https://x.com/RafaelDavisH')
.find('svg')
.should('have.attr', 'data-test-label', 'x-icon');
context('Website', () => {
context('Author with no website link', () => {
before(() => {
cy.visit('/author/rafael/');
});

it('should not show a website link and icon', () => {
cy.get(selectors.socialMedia.website.link).should('not.exist');
cy.get(selectors.socialMedia.website.icon).should('not.exist');
});
});

context('Author with a website link', () => {
before(() => {
cy.visit('/author/freecodecamp/');
});

it('should show a website link and icon', () => {
cy.get(selectors.socialMedia.website.link)
.should('have.attr', 'href', 'https://www.freecodecamp.org')
.find('svg')
.should('have.attr', 'data-test-label', 'website-icon');
});
});
});
});

context('Website', () => {
context('Author with no website link', () => {
// Note: All authors should have an RSS link and icon
context('RSS', () => {
before(() => {
cy.visit('/author/rafael/');
});

it('should not show a website link and icon', () => {
cy.get(selectors.socialMedia.website.link).should('not.exist');
cy.get(selectors.socialMedia.website.icon).should('not.exist');
// TODO: Links for RSS feeds are currently broken, so fix and test them in
// a future PR
it('should show an RSS link and icon', () => {
cy.get(selectors.socialMedia.rss.link)
// .should('have.attr', 'href', 'https://feedly.com/i/subscription/feed/http://localhost:8080/news/author/rafael/rss/')
.find('svg')
.should('have.attr', 'data-test-label', 'rss-icon');
});
});
});
});
});

context('Hashnode sourced', () => {
context('Author with profile image', () => {
beforeEach(() => {
cy.visit('/author/rafaeldavish/');
});

it('should render', () => {
cy.contains(selectors.authorName, 'Rafael D. Hernandez');
});

it("should show the author's profile image", () => {
cy.get(selectors.authorProfileImage).then($el =>
expect($el[0].tagName.toLowerCase()).to.equal('img')
);
});

it("the author profile image should contain an `alt` attribute with the author's name", () => {
cy.get<HTMLImageElement>(selectors.authorProfileImage).then($el =>
expect($el[0].alt).to.equal('Rafael D. Hernandez')
);
});

it(`should show 2 posts on load`, () => {
getPostCards().should('have.length', 2);
});

it('should show the correct number of total posts', () => {
loadAndCountAllPostCards(selectors.authorPostCount);
});
});

context('Social media', () => {
context('Website', () => {
context('Author with a website link', () => {
before(() => {
cy.visit('/author/freecodecamp/');
cy.visit('/author/rafaeldavish/');
});

it('should show a website link and icon', () => {
cy.get(selectors.socialMedia.website.link)
.should('have.attr', 'href', 'https://www.freecodecamp.org')
.should('have.attr', 'href', 'https://rafaeldavis.dev')
.find('svg')
.should('have.attr', 'data-test-label', 'website-icon');
});
});
});

context('GitHub', () => {
context('Author with a GitHub profile link', () => {
before(() => {
cy.visit('/author/rafaeldavish/');
});

it('should show a GitHub link and icon', () => {
cy.get(selectors.socialMedia.github.link)
.should('have.attr', 'href', 'https://github.com/RafaelDavisH')
.find('svg')
.should('have.attr', 'data-test-label', 'github-icon');
});
});
});

// Note: All authors should have an RSS link and icon
context('RSS', () => {
before(() => {
cy.visit('/author/rafael/');
cy.visit('/author/rafaeldavish/');
});

// TODO: Links for RSS feeds are currently broken, so fix and test them in

Check notice on line 269 in cypress/e2e/espanol/author/author.cy.ts

View check run for this annotation

codefactor.io / CodeFactor

cypress/e2e/espanol/author/author.cy.ts#L269

Unresolved 'todo' comment. (eslint/no-warning-comments)
// a future PR
it('should show an RSS link and icon', () => {
cy.get(selectors.socialMedia.rss.link)
// .should('have.attr', 'href', 'https://feedly.com/i/subscription/feed/http://localhost:8080/news/author/rafael/rss/')
// .should(
// 'have.attr',
// 'href',
// 'https://feedly.com/i/subscription/feed/http://localhost:8080/news/author/rafaeldavish/rss/'
// )
.find('svg')
.should('have.attr', 'data-test-label', 'rss-icon');
});
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/espanol/landing/i18n.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const selectors = {
}
};

describe('Landing i18n (Ghost sourced)', () => {
describe('Landing i18n', () => {
before(() => {
// Update baseUrl to include current language
Cypress.config('baseUrl', 'http://localhost:8080/espanol/news/');
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/espanol/landing/landing.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const selectors = {
banner: "[data-test-label='banner']"
};

describe('Landing (Ghost sourced)', () => {
describe('Landing', () => {
before(() => {
// Update baseUrl to include current language
Cypress.config('baseUrl', 'http://localhost:8080/espanol/news/');
Expand Down
Loading
Loading