-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #126 from Erik-Outreach/develop
add fetch collector
- Loading branch information
Showing
8 changed files
with
255 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
const LOG_TYPE = require('../constants').LOG_TYPES; | ||
const CONSTANTS = require('../constants'); | ||
const LogFormat = require("./LogFormat"); | ||
|
||
module.exports = class LogCollectCypressFetch { | ||
|
||
constructor(collectorState, config) { | ||
this.config = config; | ||
this.collectorState = collectorState; | ||
|
||
this.format = new LogFormat(config); | ||
} | ||
|
||
register() { | ||
const formatFetch = (options) => (options.alias !== undefined ? '(' + options.alias + ') ' : '') + | ||
(options.consoleProps["Request went to origin?"] !== 'yes' ? 'STUBBED ' : '') + | ||
options.consoleProps.Method + ' ' + options.consoleProps.URL; | ||
|
||
const formatDuration = (durationInMs) => | ||
durationInMs < 1000 ? `${durationInMs} ms` : `${durationInMs / 1000} s`; | ||
|
||
Cypress.on('log:added', (options) => { | ||
if (options.instrument === 'command' && options.name === 'request' && options.displayName === 'fetch') { | ||
const log = formatFetch(options); | ||
const severity = options.state === 'failed' ? CONSTANTS.SEVERITY.WARNING : ''; | ||
this.collectorState.addLog([LOG_TYPE.CYPRESS_FETCH, log, severity], options.id); | ||
} | ||
}); | ||
|
||
Cypress.on('log:changed', async (options) => { | ||
if ( | ||
options.instrument === 'command' && options.name === 'request' && options.displayName === 'fetch' && | ||
options.state !== 'pending' | ||
) { | ||
let statusCode; | ||
|
||
statusCode = options.consoleProps["Response Status Code"]; | ||
|
||
const isSuccess = statusCode && (statusCode + '')[0] === '2'; | ||
const severity = isSuccess ? CONSTANTS.SEVERITY.SUCCESS : CONSTANTS.SEVERITY.WARNING; | ||
let log = formatFetch(options); | ||
|
||
if (options.consoleProps.Duration) { | ||
log += ` (${formatDuration(options.consoleProps.Duration)})`; | ||
} | ||
if (statusCode) { | ||
log += `\nStatus: ${statusCode}`; | ||
} | ||
if (options.err && options.err.message) { | ||
log += ' - ' + options.err.message; | ||
} | ||
|
||
if ( | ||
!isSuccess && | ||
options.consoleProps["Response Body"] | ||
) { | ||
log += `\nResponse body: ${await this.format.formatXhrBody(options.consoleProps["Response Body"])}`; | ||
} | ||
|
||
this.collectorState.updateLog(log, severity, options.id); | ||
} | ||
}); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
"cons:error", | ||
"cy:log", | ||
"cy:xhr", | ||
"cy:fetch", | ||
"cy:request", | ||
"cy:intercept", | ||
"cy:route", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
describe('Fetch Api', () => { | ||
it('Stubbed failed fetch API', () => { | ||
cy.visit('/commands/network-requests'); | ||
|
||
cy.intercept( | ||
{ | ||
method: 'PUT', | ||
url: 'comments/*', | ||
}, | ||
{ | ||
statusCode: 404, | ||
body: {error: 'Test message.'}, | ||
delay: 500, | ||
} | ||
).as('putComment'); | ||
|
||
cy.window().then((w) => { | ||
fetch('/comments/10', { | ||
method: 'PUT', | ||
body: 'test', | ||
}); | ||
}); | ||
|
||
cy.wait('@putComment'); | ||
|
||
cy.get('.breaking-get', {timeout: 1}); | ||
}) | ||
|
||
context('Timeout', () => { | ||
|
||
it('forceNetworkError ', () => { | ||
cy.visit('/commands/network-requests'); | ||
|
||
cy.intercept( | ||
{ | ||
method: 'PUT', | ||
url: 'comments/*', | ||
|
||
}, | ||
{ | ||
forceNetworkError: true, | ||
} | ||
).as('putComment'); | ||
|
||
cy.window().then((w) => { | ||
fetch('/comments/10', { | ||
method: 'PUT', | ||
body: 'test', | ||
}); | ||
}); | ||
|
||
cy.wait('@putComment'); | ||
|
||
cy.get('.breaking-get', {timeout: 1}); | ||
}); | ||
|
||
// Currently Cypress can't handle fetch Abort properly. It produces an unhandled entry, while the request remains "pending": | ||
// cy:command ✘ uncaught exception AbortError: The user aborted a request. | ||
it('timeout using AbortController', () => { | ||
cy.visit('/commands/network-requests'); | ||
|
||
cy.intercept( | ||
{ | ||
method: 'PUT', | ||
url: 'comments/*', | ||
|
||
}, | ||
{ | ||
delay: 500, | ||
} | ||
).as('putComment'); | ||
|
||
cy.window().then((w) => { | ||
|
||
const controller = new AbortController(); | ||
setTimeout(() => controller.abort(), 100); | ||
|
||
fetch('/comments/10', { | ||
method: 'PUT', | ||
body: 'test', | ||
signal: controller.signal | ||
}); | ||
}); | ||
|
||
cy.wait('@putComment'); | ||
|
||
cy.get('.breaking-get', {timeout: 1}); | ||
}); | ||
}); | ||
|
||
|
||
context('Real Fetch Requests', () => { | ||
const testRealFetchRequest = (options) => { | ||
cy.visit('/commands/network-requests'); | ||
|
||
if (options.interceptPath) { | ||
// only intercepted fetch requests logs a response body. Read more at https://github.com/cypress-io/cypress/issues/17656 | ||
cy.intercept(options.interceptPath); | ||
} | ||
|
||
cy.window().then((window) => { | ||
const document = window.document; | ||
|
||
// Create a div to put a message to after receiving the fetch response | ||
const containerDiv = document.createElement('div'); | ||
containerDiv.className = 'network-request-message'; | ||
const networkComment = document.querySelector('.network-comment'); | ||
networkComment.after(containerDiv); | ||
|
||
// Crate a button that triggers the fetch | ||
const button = document.createElement('button'); | ||
button.className = 'network-request btn btn-primary'; | ||
button.innerHTML = 'Fetch Request '; | ||
button.addEventListener('click', () => | ||
fetch(options.url).then(() => { | ||
containerDiv.innerHTML = 'received response'; | ||
}) | ||
); | ||
containerDiv.before(button); | ||
}); | ||
|
||
cy.get('.network-request-message').should('not.contain', 'received response'); | ||
cy.get('.network-request').click(); | ||
cy.get('.network-request-message').should('contain', 'received response'); | ||
|
||
cy.get('.breaking-get', {timeout: 100}); // longer timeout to ensure fetch log update is included | ||
}; | ||
|
||
it('Fetch successful without interceptor', () => | ||
testRealFetchRequest({ | ||
url: 'https://jsonplaceholder.cypress.io/comments/1', | ||
})); | ||
|
||
it('Fetch failed without interceptors', () => | ||
testRealFetchRequest({ | ||
url: 'https://www.mocky.io/v2/5ec993803000009700a6ce1f', | ||
})); | ||
|
||
it('Fetch failed with interceptors', () => | ||
testRealFetchRequest({ | ||
url: 'https://www.mocky.io/v2/5ec993803000009700a6ce1f', | ||
interceptPath: 'https://www.mocky.io/**/*', | ||
})); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters