使用Selenium捕获REST调用

时间:2016-12-31 17:45:24

标签: javascript rest selenium webdriver-io

我使用Selenium作为测试运行器和Selenium API的webdriver.io javascript库运行集成测试。 我的测试如下: 我加载一个html页面,然后单击一个按钮。我想检查是否调用了Get REST调用。

我找到了一个名为webdriverajax的webdriver.io插件,它打算符合我的要求,但它不起作用。

任何想法如何捕获休息电话?

2 个答案:

答案 0 :(得分:0)

你可以通过使用selenium代码之外的自定义HttpClient类来实现这一点。据我所知,selenium不支持此功能。

假设当您点击该按钮时,它会调用REST服务,可以从HTML DOM元素中获取该网址。然后您可以使用自定义代码验证是否有URL是否可访问。然后您可以根据status code或其他机制确定您的测试是通过还是失败。

FileDownloader.java(示例代码段)

private String downloader(WebElement element, String attribute) throws IOException, NullPointerException, URISyntaxException {
        String fileToDownloadLocation = element.getAttribute(attribute);
        if (fileToDownloadLocation.trim().equals("")) throw new NullPointerException("The element you have specified does not link to anything!");

        URL fileToDownload = new URL(fileToDownloadLocation);
        File downloadedFile = new File(this.localDownloadPath + fileToDownload.getFile().replaceFirst("/|\\\\", ""));
        if (downloadedFile.canWrite() == false) downloadedFile.setWritable(true);

        HttpClient client = new DefaultHttpClient();
        BasicHttpContext localContext = new BasicHttpContext();

        LOG.info("Mimic WebDriver cookie state: " + this.mimicWebDriverCookieState);
        if (this.mimicWebDriverCookieState) {
            localContext.setAttribute(ClientContext.COOKIE_STORE, mimicCookieState(this.driver.manage().getCookies()));
        }

        HttpGet httpget = new HttpGet(fileToDownload.toURI());
        HttpParams httpRequestParameters = httpget.getParams();
        httpRequestParameters.setParameter(ClientPNames.HANDLE_REDIRECTS, this.followRedirects);
        httpget.setParams(httpRequestParameters);

        LOG.info("Sending GET request for: " + httpget.getURI());
        HttpResponse response = client.execute(httpget, localContext);
        this.httpStatusOfLastDownloadAttempt = response.getStatusLine().getStatusCode();
        LOG.info("HTTP GET request status: " + this.httpStatusOfLastDownloadAttempt);
        LOG.info("Downloading file: " + downloadedFile.getName());
        FileUtils.copyInputStreamToFile(response.getEntity().getContent(), downloadedFile);
        response.getEntity().getContent().close();

        String downloadedFileAbsolutePath = downloadedFile.getAbsolutePath();
        LOG.info("File downloaded to '" + downloadedFileAbsolutePath + "'");

        return downloadedFileAbsolutePath;
    }

<强> TestClass.java

@Test
public void downloadAFile() throws Exception {


       FileDownloader downloadTestFile = new FileDownloader(driver);
        driver.get("http://www.localhost.com/downloadTest.html");
        WebElement downloadLink = driver.findElement(By.id("fileToDownload"));
        String downloadedFileAbsoluteLocation = downloadTestFile.downloadFile(downloadLink);

        assertThat(new File(downloadedFileAbsoluteLocation).exists(), is(equalTo(true)));
        assertThat(downloadTestFile.getHTTPStatusOfLastDownloadAttempt(), is(equalTo(200)));
 // you can use status code to valid  the REST URL
    }

Here是参考。

注意:这可能不完全符合您的要求,但您可以根据需要获得一些想法并进行相应修改。

另请参考BrowserMob Proxy使用此功能,您也可以实现您想要的效果。

答案 1 :(得分:0)

问题是webdriver.io版本。显然,webdriverajax只能使用webdriver.io v3.x,但不适用于v4.x.我用的是v4.5.2。

我决定不使用插件并为window.XMLHttpRequest实现模拟 打开并发送方法,如下:

proxyXHR() {
  this.browser.execute(() => {
    const namespace = '__scriptTests';
    window[namespace] = { open: [], send: [] };
    const originalOpen = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function (...args) {
      window[namespace].open.push({
        method: args[0],
        url: args[1],
        async: args[2],
        user: args[3],
        password: args[4]
      });
      originalOpen.apply(this, [].slice.call(args));
    };
    window.XMLHttpRequest.prototype.send = function (...args) {
      window[namespace].send.push(JSON.parse(args[0]));
    };
  });
}

getXHRsInfo() {
  const result = this.browser.execute(() => {
    const namespace = '__scriptTests';
    return window[namespace];
  });
  return result.value;
}