Intercept Service
wdio-intercept-service ist ein Paket von Drittanbietern, weitere Informationen finden Sie auf GitHub | npm
🕸 HTTP-Ajax-Aufrufe in webdriver.io erfassen und überprüfen
Dies ist ein Plugin für webdriver.io. Wenn Sie es noch nicht kennen, schauen Sie es sich an, es ist ziemlich cool.
Obwohl Selenium und Webdriver für E2E und insbesondere UI-Tests verwendet werden, möchten Sie möglicherweise HTTP-Anfragen bewerten, die von Ihrem Client-Code durchgeführt werden (z. B. wenn Sie kein unmittelbares UI-Feedback haben, wie bei Metriken oder Tracking-Aufrufen). Mit wdio-intercept-service können Sie Ajax-HTTP-Aufrufe abfangen, die durch eine Benutzeraktion (z. B. einen Knopfdruck usw.) ausgelöst werden, und später Aussagen über die Anfrage und die entsprechenden Antworten machen.
Es gibt jedoch einen Haken: Sie können keine HTTP-Aufrufe abfangen, die beim Laden der Seite initiiert werden (wie in den meisten SPAs), da einige Einrichtungsarbeiten erforderlich sind, die erst nach dem Laden der Seite durchgeführt werden können (aufgrund von Einschränkungen in Selenium). Das bedeutet, dass Sie nur Anfragen erfassen können, die innerhalb eines Tests initiiert wurden. Wenn Sie damit einverstanden sind, könnte dieses Plugin für Sie geeignet sein, also lesen Sie weiter.
Voraussetzungen
- webdriver.io v5.x oder neuer.
Achtung! Wenn Sie noch webdriver.io v4 verwenden, verwenden Sie bitte den v2.x-Branch dieses Plugins!
Installation
npm install wdio-intercept-service -D
Verwendung
Verwendung mit WebDriver CLI
Es sollte so einfach sein, wie wdio-intercept-service zu Ihrer wdio.conf.js
hinzuzufügen:
exports.config = {
// ...
services: ['intercept']
// ...
};
und alles ist eingerichtet.
Verwendung mit WebDriver Standalone
Bei der Verwendung von WebdriverIO Standalone müssen die Funktionen before
und beforeTest
/ beforeScenario
manuell aufgerufen werden.
import { remote } from 'webdriverio';
import WebdriverAjax from 'wdio-intercept-service'
const WDIO_OPTIONS = {
port: 9515,
path: '/',
capabilities: {
browserName: 'chrome'
},
}
let browser;
const interceptServiceLauncher = WebdriverAjax();
beforeAll(async () => {
browser = await remote(WDIO_OPTIONS)
interceptServiceLauncher.before(null, null, browser)
})
beforeEach(async () => {
interceptServiceLauncher.beforeTest()
})
afterAll(async () => {
await client.deleteSession()
});
describe('', async () => {
... // See example usage
});
Nach der Initialisierung werden einige zugehörige Funktionen zu Ihrer Browser-Befehlskette hinzugefügt (siehe API).
Schnellstart
Beispiel für die Verwendung:
browser.url('http://foo.bar');
browser.setupInterceptor(); // capture ajax calls
browser.expectRequest('GET', '/api/foo', 200); // expect GET request to /api/foo with 200 statusCode
browser.expectRequest('POST', '/api/foo', 400); // expect POST request to /api/foo with 400 statusCode
browser.expectRequest('GET', /\/api\/foo/, 200); // can validate a URL with regex, too
browser.click('#button'); // button that initiates ajax request
browser.pause(1000); // maybe wait a bit until request is finished
browser.assertRequests(); // validate the requests
Details zu Anfragen erhalten:
browser.url('http://foo.bar')
browser.setupInterceptor();
browser.click('#button')
browser.pause(1000);
var request = browser.getRequest(0);
assert.equal(request.method, 'GET');
assert.equal(request.response.headers['content-length'], '42');
Unterstützte Browser
Es sollte mit etwas neueren Versionen aller Browser funktionieren. Bitte melden Sie ein Problem, wenn es mit Ihrem Browser nicht zu funktionieren scheint.
API
Lesen Sie die TypeScript-Deklarationsdatei für die vollständige Syntax der benutzerdefinierten Befehle, die dem WebdriverIO-Browserobjekt hinzugefügt wurden. Im Allgemeinen kann jede Methode, die ein "options"-Objekt als Parameter verwendet, ohne diesen Parameter aufgerufen werden, um das Standardverhalten zu erhalten. Diese "optionalen Options"-Objekte werden mit ?: = {}
gekennzeichnet, und die Standardwerte sind für jede Methode beschrieben.
Optionsbeschreibungen
Diese Bibliothek bietet eine geringe Konfigurationsmöglichkeit bei der Ausgabe von Befehlen. Konfigurationsoptionen, die von mehreren Methoden verwendet werden, werden hier beschrieben (siehe jede Methodendefinition, um die spezifische Unterstützung zu bestimmen).
orderBy
('START' | 'END'
): Diese Option steuert die Reihenfolge der vom Interceptor erfassten Anfragen, wenn sie an Ihren Test zurückgegeben werden. Um die Kompatibilität mit bestehenden Versionen dieser Bibliothek zu gewährleisten, ist die Standardsortierung'END'
, was dem Zeitpunkt entspricht, zu dem die Anfrage abgeschlossen wurde. Wenn Sie die OptionorderBy
auf'START'
setzen, werden die Anfragen nach dem Zeitpunkt geordnet, zu dem sie gestartet wurden.includePending
(boolean
): Diese Option steuert, ob noch nicht abgeschlossene Anfragen zurückgegeben werden. Um die Kompatibilität mit bestehenden Versionen dieser Bibliothek zu gewährleisten, ist der Standardwertfalse
, und es werden nur abgeschlossene Anfragen zurückgegeben.
browser.setupInterceptor()
Erfasst Ajax-Aufrufe im Browser. Sie müssen immer die Setup-Funktion aufrufen, um später Anfragen auswerten zu können.
browser.disableInterceptor()
Verhindert die weitere Erfassung von Ajax-Aufrufen im Browser. Alle erfassten Anfrageinformationen werden entfernt. Die meisten Benutzer müssen den Interceptor nicht deaktivieren, aber wenn ein Test besonders lang läuft oder die Kapazität des Sitzungsspeichers überschreitet, kann das Deaktivieren des Interceptors hilfreich sein.
browser.excludeUrls(urlRegexes: (string | RegExp)[])
Schließt Anfragen von bestimmten URLs von der Aufzeichnung aus. Es akzeptiert ein Array von Strings oder regulären Ausdrücken. Vor dem Schreiben in den Speicher wird die URL der Anfrage gegen jeden String oder regulären Ausdruck getestet. Wenn sie übereinstimmt, wird die Anfrage nicht in den Speicher geschrieben. Wie disableInterceptor kann dies hilfreich sein, wenn Probleme mit der Überschreitung der Kapazität des Sitzungsspeichers auftreten.
browser.expectRequest(method: string, url: string, statusCode: number)
Erstellen Sie Erwartungen zu den Ajax-Anfragen, die während des Tests initiiert werden. Kann (und sollte) verkettet werden. Die Reihenfolge der Erwartungen sollte der Reihenfolge der durchgeführten Anfragen entsprechen.
method
(String
): HTTP-Methode, die erwartet wird. Kann alles sein, wasxhr.open()
als erstes Argument akzeptiert.url
(String
|RegExp
): exakte URL, die in der Anfrage aufgerufen wird, als String oder RegExp zum AbgleichstatusCode
(Number
): erwarteter Statuscode der Antwort
browser.getExpectations()
Hilfsmethode. Gibt alle Erwartungen zurück, die Sie bis zu diesem Zeitpunkt erstellt haben
browser.resetExpectations()
Hilfsmethode. Setzt alle Erwartungen zurück, die Sie bis zu diesem Zeitpunkt erstellt haben
browser.assertRequests({ orderBy?: 'START' | 'END' }?: = {})
Rufen Sie diese Methode auf, wenn alle erwarteten Ajax-Anfragen abgeschlossen sind. Sie vergleicht die Erwartungen mit den tatsächlich gestellten Anfragen und überprüft Folgendes:
- Anzahl der gestellten Anfragen
- Die Reihenfolge der Anfragen
- Die Methode, die URL und der Statuscode sollten für jede gestellte Anfrage übereinstimmen
- Das Options-Objekt hat standardmäßig den Wert
{ orderBy: 'END' }
, d.h. wann die Anfragen abgeschlossen wurden, um konsistent mit dem Verhalten von v4.1.10 und früher zu sein. Wenn die OptionorderBy
auf'START'
gesetzt ist, werden die Anfragen danach geordnet, wann sie von der Seite initiiert wurden.
browser.assertExpectedRequestsOnly({ inOrder?: boolean, orderBy?: 'START' | 'END' }?: = {})
Ähnlich wie browser.assertRequests
, überprüft aber nur die Anfragen, die Sie in Ihren expectRequest
-Anweisungen angeben, ohne alle Netzwerkanfragen abbilden zu müssen, die möglicherweise um diese herum stattfinden. Wenn die Option inOrder
true
ist (Standard), wird erwartet, dass die Anfragen in derselben Reihenfolge gefunden werden, wie sie mit expectRequest
eingerichtet wurden.
browser.getRequest(index: number, { includePending?: boolean, orderBy?: 'START' | 'END' }?: = {})
Um anspruchsvollere Behauptungen über eine bestimmte Anfrage aufzustellen, können Sie Details für eine bestimmte Anfrage abrufen. Sie müssen den 0-basierten Index der Anfrage angeben, auf die Sie zugreifen möchten, in der Reihenfolge, in der die Anfragen abgeschlossen wurden (Standard) oder initiiert wurden (durch Übergabe der Option orderBy: 'START'
).
index
(number
): Nummer der Anfrage, auf die Sie zugreifen möchtenoptions
(object
): Konfigurationsoptionenoptions.includePending
(boolean
): Ob noch nicht abgeschlossene Anfragen zurückgegeben werden sollen. Standardmäßig ist dies false, um dem Verhalten der Bibliothek in v4.1.10 und früher zu entsprechen.options.orderBy
('START' | 'END'
): Wie die Anfragen geordnet werden sollen. Standardmäßig ist dies'END'
, um dem Verhalten der Bibliothek in v4.1.10 und früher zu entsprechen. Bei'START'
werden die Anfragen nach dem Zeitpunkt der Initiierung und nicht nach dem Zeitpunkt des Abschlusses der Anfrage geordnet. (Da eine ausstehende Anfrage noch nicht abgeschlossen ist, kommen bei der Sortierung nach'END'
alle ausstehenden Anfragen nach allen abgeschlossenen Anfragen.)
Gibt request
-Objekt zurück:
request.url
: angeforderte URLrequest.method
: verwendete HTTP-Methoderequest.body
: Nutzlast/Body-Daten, die in der Anfrage verwendet wurdenrequest.headers
: HTTP-Header der Anfrage als JS-Objektrequest.pending
: boolesches Flag, ob diese Anfrage abgeschlossen ist (d.h. eineresponse
-Eigenschaft hat) oder in Bearbeitung ist.request.response
: ein JS-Objekt, das nur vorhanden ist, wenn die Anfrage abgeschlossen ist (d.h.request.pending === false
), das Daten über die Antwort enthält.request.response?.headers
: HTTP-Header der Antwort als JS-Objektrequest.response?.body
: Antworttext (wird wenn möglich als JSON geparst)request.response?.statusCode
: Statuscode der Antwort
Ein Hinweis zu request.body
: wdio-intercept-service versucht, den Anforderungstext wie folgt zu parsen:
- String: Gibt einfach den String zurück (
'value'
) - JSON: Parst das JSON-Objekt mit
JSON.parse()
(({ key: value })
) - FormData: Gibt die FormData im Format
{ key: [value1, value2, ...] }
aus - ArrayBuffer: Versucht, den Puffer in einen String zu konvertieren (experimentell)
- Alles andere: Verwendet ein brutales
JSON.stringify()
auf Ihren Daten. Viel Glück!
Für die fetch
-API unterstützen wir nur String- und JSON-Daten!
browser.getRequests({ includePending?: boolean, orderBy?: 'START' | 'END' }?: = {})
Ruft alle erfassten Anfragen als Array ab und unterstützt dieselben optionalen Optionen wie getRequest
.
Gibt ein Array von request
-Objekten zurück.
browser.hasPendingRequests()
Eine Hilfsmethode, die prüft, ob noch HTTP-Anfragen ausstehen. Kann von Tests verwendet werden, um sicherzustellen, dass alle Anfragen innerhalb einer angemessenen Zeit abgeschlossen sind, oder um zu überprüfen, ob ein Aufruf von getRequests()
oder assertRequests()
alle gewünschten HTTP-Anfragen enthält.
Gibt einen booleschen Wert zurück
TypeScript-Unterstützung
Dieses Plugin stellt seine eigenen TS-Typen bereit. Verweisen Sie einfach in Ihrer tsconfig auf die Typerweiterungen, wie hier erwähnt:
"compilerOptions": {
// ..
"types": ["node", "webdriverio", "wdio-intercept-service"]
},
Ausführen der Tests
Aktuelle Versionen von Chrome und Firefox sind erforderlich, um die Tests lokal auszuführen. Möglicherweise müssen Sie die Abhängigkeiten chromedriver
und geckodriver
aktualisieren, damit sie mit der auf Ihrem System installierten Version übereinstimmen.
npm test
Mitwirken
Ich freue mich über jeden Beitrag. Öffnen Sie einfach ein Issue oder reichen Sie direkt einen PR ein.
Bitte beachten Sie, dass diese Interceptor-Bibliothek für die Arbeit mit Legacy-Browsern wie Internet Explorer geschrieben wurde. Daher muss jeder Code, der in lib/interceptor.js
verwendet wird, mindestens von der JavaScript-Laufzeitumgebung des Internet Explorer geparst werden können.
Lizenz
MIT