/// const showSidePanelContent = () => { cy.get('[data-testid=profileSidePanel] h4').should('have.text', 'Test User1'); cy.get('[data-testid=profileSidePanel] .modal-body p').first().within(() => { cy.contains('Location: Denver, CO, US') .and('contain', 'Skill Level: Professional') .and('contain', 'Joined JamKazam: 08-26-2021') .and('contain', 'Last Active:') .and('contain', 'Latency To Me:'); cy.get('.latency-badge').contains('UNKNOWN'); }); cy.get('[data-testid=profileSidePanel] .modal-body').first().within(() => { cy.get('[data-testid=biography]').contains('Biography of Test User1'); //instruments cy.get('[data-testid=instruments]').contains('Acoustic Guitar: Expert'); cy.get('[data-testid=instruments]').contains('Keyboard: Expert'); //genres cy.get('[data-testid=genres]').contains('classical, blues'); //bands cy.get('[data-testid=bands]').contains('The Band'); //performance_samples //cy.get('[data-testid=performance_samples]').contains('The Band') //online presence cy.get('[data-testid=online_presences]').contains('Soundcloud').should('have.attr', 'href').and('eq', 'https://www.soundcloud.com/testuser'); cy.get('[data-testid=online_presences]').contains('Reverbnation').should('have.attr', 'href').and('eq', 'https://www.reverbnation.com/testuser'); cy.get('[data-testid=online_presences]').contains('Bandcamp').should('have.attr', 'href').and('eq', 'https://testuser.bandcamp.com'); cy.get('[data-testid=online_presences]').contains('Fandalism').should('have.attr', 'href').and('eq', 'https://www.fandalism.com/testuser'); cy.get('[data-testid=online_presences]').contains('Youtube').should('have.attr', 'href').and('eq', 'https://www.youtube.com/testuser'); cy.get('[data-testid=online_presences]').contains('Facebook').should('have.attr', 'href').and('eq', 'https://www.facebook.com/testuser'); cy.get('[data-testid=online_presences]').contains('Twitter').should('have.attr', 'href').and('eq', 'https://www.twitter.com/testuser'); }); }; const closeSidePanel = () => { cy.get('[data-testid=profileSidePanel] .modal-header button.close').click(); }; describe('Friends page without data', () => { beforeEach(() => { cy.stubAuthenticate(); cy.intercept('POST', /\S+\/filter/, { musicians: [] }).as("getPeople_empty"); }); it('from_location is unchecked', () => { cy.visit('/friends'); //default api call with from_location parameter turned off cy.wait('@getPeople_empty') .then(interception => { assert.isNotNull(interception.response.body, '1st API call'); }) .its('request.body') .should('deep.contain', { from_location: false }); //now it automatically turns on from_location parameter and fetches again cy.wait('@getPeople_empty') .then(interception => { assert.isNotNull(interception.response.body, '2nd API call - (prefetched)'); }) .its('request.body') .should('deep.contain', { from_location: true }); cy.contains('No Records!'); cy.get('[data-testid=btnUpdateSearch]').click(); cy.get('[data-testid=modalUpdateSearch] input[name=from_location]').check(); cy.wait(1000); cy.get('[data-testid=btnSubmitSearch]').click(); //default api call with from_location parameter turned on cy.wait('@getPeople_empty') .then(interception => { assert.isNotNull(interception.response.body, '3th API call'); }) .its('request.body') .should('deep.contain', { from_location: true }); cy.contains('No Records!'); }); }); describe('Friends page with data', () => { beforeEach(() => { cy.stubAuthenticate({ id: '2' }); //currentUser id is 2 - people.yaml fixture cy.intercept('POST', /\S+\/filter\?offset=0/, { fixture: 'people_page1' }).as('getPeople_page1'); cy.intercept('POST', /\S+\/filter\?offset=10/, { fixture: 'people_page2' }).as('getPeople_page2'); cy.intercept('POST', /\S+\/filter\?offset=20/, { fixture: 'people_page3' }).as('getPeople_page3'); cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' }); }); describe('listing users', () => { beforeEach(() => { cy.visit('/friends'); }); describe('in desktop', () => { beforeEach(() => { cy.viewport('macbook-13'); }); it('paginate', () => { cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 10); cy.wait('@getPeople_page2') cy.get('[data-testid=paginate-next-page]').click(); cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 20); //cy.get('[data-testid=paginate-next-page]').should('not.exist'); cy.get('[data-testid=paginate-next-page]').click(); cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 30); cy.get('[data-testid=paginate-next-page]').should('not.exist'); }); it('show profiles', () => { cy.contains('Find New Friends').should('exist'); cy.contains('Update Search').should('exist'); cy.contains('Reset Filters').should('exist'); cy.get('[data-testid=peopleListTable] > tbody tr') .should('have.length', 10) .first() .contains('Test User1'); }); it('click profile name', () => { //open side panel by clicking name cy.get('[data-testid=peopleListTable]').find('.person-link').first().within(() => { cy.contains("Test User1").click() }) //cy.get('[data-testid=peopleListTable]').find('.person-link').first().click() showSidePanelContent(); closeSidePanel(); }); it('click more button', () => { //open side panel by clicking more button cy.get('[data-testid=peopleListTable] > tbody tr') .first() .find('[data-testid=btnMore]') .click(); showSidePanelContent(); closeSidePanel(); }); it('click more link', () => { //open side panel by clicking more link cy.get('[data-testid=peopleListTable] > tbody tr') .first() .find('[data-testid=linkMore]') .click(); showSidePanelContent(); closeSidePanel(); }); it('click description more link', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .first() .find('td[data-testid=biography-col]') .within(() => { cy.contains('More').click(); }); showSidePanelContent(); closeSidePanel(); }); it('click instruments more link', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .first() .find('[data-testid=instrumentList]') .within(() => { cy.get('div').should('have.length', 4); //show only 4 instruments plus more link cy.contains('Acoustic Guitar: Expert'); cy.contains('Keyboard: Expert'); cy.contains('Ukulele: Expert'); cy.contains('Voice: Expert'); cy.contains('More').click(); }); showSidePanelContent(); closeSidePanel(); }); it('click genres more link', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .first() .find('td[data-testid=genres-col]') .within(() => { cy.contains('More').click(); }); showSidePanelContent(); closeSidePanel(); }); }); describe('in mobile', () => { beforeEach(() => { cy.viewport('iphone-6'); }); it('show profile', () => { cy.get('[data-testid=peopleSwiper] .swiper-slide').should('have.length', 10); cy.get('[data-testid=peopleSwiper] .swiper-slide') .eq(0) .contains('Test User1'); cy.get('[data-testid=peopleSwiper] .swiper-slide') .eq(0) .should('be.visible'); cy.get('[data-testid=peopleSwiper] .swiper-slide') .eq(2) .should('not.be.visible'); }); it('show all profile description', () => { cy.get('[data-testid=peopleSwiper] .swiper-slide') .first() .find('[data-testid=mobBiography]') .should('not.contain', 'More'); }); it('show all instruments', () => { cy.get('[data-testid=peopleSwiper] .swiper-slide') .first() .find('[data-testid=instrumentList] div') .its('length') .should('be.gte', 1); cy.get('[data-testid=peopleSwiper] .swiper-slide') .first() .find('[data-testid=instrumentList]') .should('not.contain', 'More'); }); it('show all genres', () => { cy.get('[data-testid=peopleSwiper] .swiper-slide') .first() .find('[data-testid=genreList] div') .its('length') .should('be.gte', 1); cy.get('[data-testid=peopleSwiper] .swiper-slide') .first() .find('[data-testid=genreList]') .should('not.contain', 'More'); }); //it.skip('click connect button', () => {}); //it.skip('click message button', () => {}); it.skip('paginate', () => { cy.get('[data-testid=peopleSwiper] .swiper-button-prev').should('have.class', 'swiper-button-disabled'); for (let i = 0; i < 19; i++) { cy.get('[data-testid=peopleSwiper] .swiper-button-next').click(); cy.wait(500); } cy.wait(500); cy.get('[data-testid=peopleSwiper] .swiper-button-next').should('have.class', 'swiper-button-disabled'); }); it('click more button', () => { cy.get('[data-testid=peopleSwiper] .swiper-slide') .first() .find('[data-testid=btnMore]') .click(); showSidePanelContent(); closeSidePanel(); }); }); }); describe('making friendship', () => { it('add friend', () => { cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' }); cy.intercept('POST', /\S+\/friend_requests/, { statusCode: 201, body: { ok: true } }); cy.visit('/friends'); cy.contains('Test User2').click(); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('not.be.disabled') .click(); // cy.get('[data-testid=confirmFriendRequestModal]').within(() => { // cy.contains('Send a friend request to Test User2'); // cy.contains('Yes').click(); // }); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('be.disabled'); cy.contains('Success! Your friend request has been sent to Test User2.'); }); it('remove friend', () => { cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'friend' }); cy.intercept('DELETE', /\S+\/friends\S+/, { statusCode: 204, body: { ok: true } }); cy.visit('/friends'); cy.contains('Test User1').click(); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=disconnect]') .should('exist') .should('not.be.disabled') .click(); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=disconnect]') .should('not.exist'); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('be.exist') .should('not.be.disabled'); }); }); describe('chat window', () => { beforeEach(() => { cy.visit('/friends'); }); it('is not disabled for friends', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .eq(0) .find('[data-testid=message]') .should('not.be.disabled') .trigger('mouseover'); cy.contains('Send a message').should('exist'); }); it('is not disabled for non friends', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .eq(1) .find('[data-testid=message]') .should('not.be.disabled'); //cy.contains('You can message this user once you are friends').should('exist') }); it('lists text messages', () => { //initially show the most recent messages on openning chat window modal let numberOfMessages = 10; cy.fixture('text_messages_page1').then(json => { cy.intercept('GET', /\S+\/text_messages\S+/, json).as('getTextMessages'); }); cy.get('[data-testid=peopleListTable] > tbody tr') .eq(0) .find('[data-testid=message]') .click(); cy.wait('@getTextMessages'); cy.get('[data-testid=textMessageModal]') .should('be.visible') .within(() => { cy.get('.text-message-row').should('have.length', numberOfMessages); //display previous messages by scrolling up const messageFixtures = ['text_messages_page2', 'text_messages_page3']; messageFixtures.forEach(fixture => { cy.fixture(fixture).then(json => { cy.intercept('GET', /\S+\/text_messages\S+/, json); cy.get('.modal-body .ScrollbarsCustom') .trigger('mouseover') .scrollTo('bottom'); cy.get('.modal-body .ScrollbarsCustom') .trigger('mouseover') .scrollTo('top'); numberOfMessages = numberOfMessages + 10; cy.get('.text-message-row').should('have.length', numberOfMessages); }); }); cy.get('button') .contains('Cancel') .should('not.be.disabled') .click(); }); cy.get('[data-testid=textMessageModal]').should('not.be.visible'); }); it('sends message by clicking send button', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .eq(0) .find('[data-testid=message]') .click(); cy.get('[data-testid=textMessageModal]').within(() => { cy.get('button') .contains('Send') .should('be.disabled'); cy.get('textarea').type('Hello'); cy.get('button') .contains('Send') .should('not.be.disabled') .click(); cy.get('textarea').should('have.value', ''); cy.get('button') .contains('Send') .should('be.disabled'); }); }); it('sends message by pressing enter key', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .eq(0) .find('[data-testid=message]') .click(); cy.get('[data-testid=textMessageModal]').within(() => { cy.get('button') .contains('Send') .should('be.disabled'); cy.get('textarea').type('Hello{enter}'); cy.get('textarea').should('have.value', ''); cy.get('button') .contains('Send') .should('be.disabled'); }); }); it('goes away by clicking close button', () => { cy.get('[data-testid=peopleListTable] > tbody tr') .eq(0) .find('[data-testid=message]') .click(); cy.get('[data-testid=textMessageModal]').within(() => { cy.get('button') .contains('Cancel') .should('not.be.disabled') .click(); }); cy.get('[data-testid=textMessageModal]').should('not.be.visible'); }); it.skip('shows received message by other user', () => { //TODO: this should be test in e2e test }); }); describe('coming from email links', () => { it.only("opens details sidebar", () => { cy.visit('/friends?open=details&id=1'); showSidePanelContent(); }); it.only("opens chat window", () => { cy.visit('/friends?open=message&id=1'); cy.get('[data-testid=textMessageModal]') .should('be.visible') cy.contains('Send Message to Test User1').should('exist'); }); it.only("sends friend request", () => { cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' }); cy.intercept('POST', /\S+\/friend_requests/, { statusCode: 201, body: { ok: true } }); cy.visit('/friends?open=connect&id=1'); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('be.disabled'); cy.contains('Success! Your friend request has been sent to Test User1.'); }); }) describe('filter', () => { const fillFilterForm = () => { //cy.get('[data-testid=btnUpdateSearch]').click(); cy.get('[data-testid=modalUpdateSearch] input[name=latency_good]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=latency_fair]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=latency_high]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_beginner]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_intermediate]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_expert]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_expert]').uncheck(); cy.get('[data-testid=modalUpdateSearch] input[name=from_location]').uncheck(); cy.get('#selInstruments') .type('Drums{enter}') .click(); cy.get('#selGenres') .type('Pop{enter}') .click(); cy.get('#selLastActive').type('Within last 1 Day{enter}'); cy.get('#selJoinedWithin').type('Within last 7 Day{enter}'); }; beforeEach(() => { cy.visit('/friends'); }); it('open and close filter modal', () => { cy.get('[data-testid=btnUpdateSearch]').click(); cy.get('[data-testid=modalUpdateSearch]').should('be.visible'); cy.get('[data-testid=modalUpdateSearch]') .contains('Cancel') .click(); cy.get('[data-testid=modalUpdateSearch]').should('not.be.visible'); }); it('render filter form', () => { cy.get('[data-testid=btnUpdateSearch]').click(); cy.get('[data-testid=modalUpdateSearch]').within(() => { cy.get('input[name=latency_good]') .should('be.checked') .next() .contains('Good (less than 40ms)'); cy.get('input[name=latency_fair]') .should('be.checked') .next() .contains('Fair (40-60ms)'); cy.get('input[name=latency_high]') .should('not.be.checked') .next() .contains('Poor (more than 60ms)'); cy.get('input[name=from_location]') .should('not.be.checked') }); }); it('reset filters', () => { cy.get('[data-testid=btnUpdateSearch]').click(); fillFilterForm(); cy.get('[data-testid=modalUpdateSearch]') .contains('Cancel') .click(); cy.get('[data-testid=btnUpdateSearch]').click(); cy.get('[data-testid=modalUpdateSearch] input[name=latency_good]').should('not.be.checked'); cy.get('[data-testid=modalUpdateSearch]') .contains('Cancel') .click(); cy.get('[data-testid=btnResetSearch]').click(); //click reset button cy.get('[data-testid=btnUpdateSearch]').click(); cy.get('[data-testid=modalUpdateSearch] input[name=latency_good]').should('be.checked'); }); it('submit filter form with params', () => { //wait for stubbed request sent to fetch data for initial page load cy.wait('@getPeople_page1').then(interception => { assert.isNotNull(interception.response.body, '1st API call has data'); }); //the subsequent request sent to perfetch data and store in redux prefetched buffer cy.wait('@getPeople_page2').then(interception => { assert.isNotNull(interception.response.body, '1st API call has data - (prefethed)'); }); cy.get('[data-testid=btnUpdateSearch]').click(); cy.wait(1000); cy.get('[data-testid=btnSubmitSearch]').click(); //wait for stubbed request sent by submitting search form without filling any form field cy.wait('@getPeople_page1') .then(interception => { assert.isNotNull(interception.response.body, '3rd API call has data'); }) .its('request.body') .should('deep.contain', { latency_good: true, latency_fair: true, latency_high: false, proficiency_beginner: true, proficiency_intermediate: true, proficiency_expert: true, instruments: [], genres: [], from_location: false }); cy.wait('@getPeople_page2').then(interception => { assert.isNotNull(interception.response.body, '4th API call has data - (prefethed)'); }); cy.get('[data-testid=btnUpdateSearch]').click(); fillFilterForm(); // change filter options cy.get('[data-testid=btnSubmitSearch]').click(); //wait for stubbed request sent by submitting search form again. but this time fill form fields cy.wait('@getPeople_page1') .then(interception => { assert.isNotNull(interception.response.body, '5th API call has data'); }) .its('request.body') .should('deep.contain', { latency_good: false, latency_fair: false, latency_high: false, proficiency_beginner: false, proficiency_intermediate: false, proficiency_expert: false, instruments: [{ value: 'drums', label: 'Drums' }], genres: ['pop'], from_location: false }); cy.wait('@getPeople_page2').then(interception => { assert.isNotNull(interception.response.body, '6th API call has data - (prefethed)'); }); }); }); });