New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run testcafe with https protocol #1985

Closed
edoardocavazza opened this Issue Dec 6, 2017 · 25 comments

Comments

Projects
None yet
8 participants
@edoardocavazza
Copy link

edoardocavazza commented Dec 6, 2017

Are you requesting a feature or reporting a bug?

Requesting a feature (maybe)

What is the current behavior?

I am unable to start testcafe using https protocol

What is the expected behavior?

Testcafe should run with ssl certificate (if provided)

Specify your

  • operating system: MacOS 10.13.1
  • testcafe version: 0.18.3
  • node.js version: 8.7.0

@AndreyBelym AndreyBelym added this to the Planned milestone Dec 6, 2017

@AndreyBelym

This comment has been minimized.

Copy link
Collaborator

AndreyBelym commented Dec 6, 2017

Hello @edoardocavazza!

It's a useful feature, because some browser API's (e.g. Apple Pay) are available only on HTTPS pages, and TestCafe HTTP end-point prevents access to them.

Right now, you can configure stunnel to encrypt traffic from TestCafe to browser. You can check "TLS front-end to a web server" on https://www.stunnel.org/config_windows.html for an example configuration.

@AndreyBelym

This comment has been minimized.

Copy link
Collaborator

AndreyBelym commented Dec 25, 2017

Requires Safari on macOS or iOS.
Example page: https://andreybelym.github.io/test-pages/gh-1985.html
Test:

fixture `ApplePay`.page`https://andreybelym.github.io/test-pages/gh-1985.html`;

test(`test`, t => t.wait(10000));
@miherlosev

This comment has been minimized.

Copy link
Collaborator

miherlosev commented Dec 25, 2017

Reproduced in Safari 11.0.2.
With TestCafe browser is raised an error:

InvalidAccessError (DOM Exception 15): Trying to call an ApplePaySession API from an insecure document.
@nesatuf

This comment has been minimized.

Copy link

nesatuf commented Mar 7, 2018

+1

@intermike

This comment has been minimized.

Copy link

intermike commented Apr 13, 2018

+1

We use crypto.subtle that is unavailable in Chrome without SSL.
And ServiceWorker too.

@awithy

This comment has been minimized.

Copy link

awithy commented Apr 17, 2018

+1

I'm really struggling with the value of an end-to-end testing framework that doesn't support https. This essentially limits it to running on localhost, which is not end-to-end.

intermike pushed a commit to intermike/testcafe that referenced this issue Apr 26, 2018

@intermike

This comment has been minimized.

Copy link

intermike commented Apr 26, 2018

@AndreyBelym, could you please review the pull requests and help me with tests and documentation. Thank you.

#2359
DevExpress/testcafe-hammerhead#1590
DevExpress/testcafe-live#19

This changes works properly for me. Tests and documentation are needed to be designed.

@AndreyBelym

This comment has been minimized.

Copy link
Collaborator

AndreyBelym commented Apr 26, 2018

Hi @intermike, thanks for contributing. Let's focus first on testcafe-hammerhead part, then when it's merged, we will discuss end-user API and CLI switches in TestCafe. I need some time to look at your work, but at first glance it's mostly fine, except a one strange expression at https://github.com/DevExpress/testcafe-hammerhead/pull/1590/files#diff-f17475e116c70c73c37dd369b8d12b6bR30 and absence of tests.

@intermike

This comment has been minimized.

Copy link

intermike commented Apr 26, 2018

@AndreyBelym

According strange expression

const originalProtocol  = opts && opts.proxyProtocol || location['proto' + 'col'];

lint throws an error for location.protocol or even location['protocol'] and I need to figure it out.

About tests.

I actually do not know how to design tests in this case. I don't mean easy checks (like https,wss protocols in all urls).
First of all it needs to generate certificates on that IP where environment will run the test.
Next, it needs to check that particular certificates are used in HTTPS handshaking properly.
And there is the blocker for me how to make tests properly and make them fast to execute.

@awithy

This comment has been minimized.

Copy link

awithy commented Apr 26, 2018

I'm not sure I 100% understand this issue, or the proposed changes. Will these changes allow TestCafe to run locally against a remote https endpoint? This use case was the one I was struggling with: to enable smoke testing from our build server against our Integration and UAT environments. Thanks for the progress.

@intermike

This comment has been minimized.

Copy link

intermike commented Apr 26, 2018

Hi @AndreyBelym

Lint error

/testcafe-hammerhead/src/client/utils/url.js
30:61 error 'protocol' is restricted from being used. Please use getters and setters for anchor element from native methods instead no-restricted-properties

Lint rule

Rule is described in https://github.com/LavrovArtem/eslint-plugin-hammerhead/blob/master/lib/index.js

Please advise what should I do with location.protocol.

@AndreyBelym

This comment has been minimized.

Copy link
Collaborator

AndreyBelym commented Apr 27, 2018

@awithy, what do you mean by

run locally against a remote https endpoint*?

You can test websites served over HTTPS as easy as websites served over HTTP, since our proxy accepts both HTTPS and HTTP as input. However all websites regardless their original protocol are served over HTTP in testing session, because our proxy supports only HTTP output. The proposed changes enable HTTPS output for proxy, so connection during testsing session will be encrypted.

@AndreyBelym

This comment has been minimized.

Copy link
Collaborator

AndreyBelym commented Apr 27, 2018

@intermike, I think it's ok to disable this check here with

/*eslint-disable no-restricted-properties*/
protocol = ...
/*eslint-enable no-restricted-properties*/
@intermike

This comment has been minimized.

Copy link

intermike commented Apr 27, 2018

@AndreyBelym Thanks for the guide. Pushed into PR.

intermike added a commit to intermike/testcafe that referenced this issue May 5, 2018

@miherlosev

This comment has been minimized.

Copy link
Collaborator

miherlosev commented May 8, 2018

It's time to discuss API, because testcafe-hammerhead's part of this feature already completed (nearly).
I propose the following API for this feature:

//Programming Interface
createTestCafe (hostname, port1, port2, sslOptions)

sslOptions.key - <Buffer> - private key in PEM format
sslOptions.cert - <Buffer> - cert in PEM format

//Command line
testcafe chrome my-tests --ssl-key test/key/agent2-key.pem --ssl-cert test/key/agent2-cert.pem
--ssl-key - <string> path to key file
--ssl-cert - <string> path to cert file

@kirovboris @AndreyBelym

@kirovboris

This comment has been minimized.

Copy link
Collaborator

kirovboris commented May 8, 2018

I believe key and cert are path to files, why should it be <Buffer>? It works this way in nodejs, but it's not quite usable. Why should we choose this approach?

@miherlosev

This comment has been minimized.

Copy link
Collaborator

miherlosev commented May 8, 2018

It works this way in nodejs, but it's not quite usable. Why should we choose this approach?

Nodejs api is polymorphically for this option. It takes string, Buffer and Object (see createsecurecontext_options).
Eventually, all of this will transformed to Buffer.

In my opinion, Buffer is the best way to specify ssl keys in programming interface.
Also, in https example from the nodejs documentation used this way.

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

@miherlosev miherlosev modified the milestones: Planned, Sprint #12 May 8, 2018

@intermike

This comment has been minimized.

Copy link

intermike commented May 9, 2018

@miherlosev
I suppose the approach runner.ssl(key, cert) does not fit the initialization order of testcafe

createTestCafe('localhost', 1337, 1338) // We need to pass certificates here
    .then(tc => {
        testcafe     = tc;
        const runner = testcafe.createRunner(); // But runner is created only here

        return runner
            .src(['tests/fixture1.js', 'tests/func/fixture3.js'])
            .browsers(['chrome', 'safari'])
            .run();
    })
    .then(failedCount => {
        console.log('Tests failed: ' + failedCount);
        testcafe.close();
    });
@kirovboris

This comment has been minimized.

Copy link
Collaborator

kirovboris commented May 10, 2018

@miherlosev

This comment has been minimized.

Copy link
Collaborator

miherlosev commented May 10, 2018

@intermike

Yes you are right. sslOptions should be declared in a factory method. I've updated the #1985 (comment)

@AndreyBelym

This comment has been minimized.

Copy link
Collaborator

AndreyBelym commented May 14, 2018

  1. I think we should also support PFX certificates (because it's more convenient to use) and rejectUnauthorized property to enable self-signed certificates for testing purposes. @miherlosev's proposal for Runner API extension is already fine with this, but for CLI we should use more general approach like:
testcafe --ssl pfx=path/to/some.pfx;rejectUnauthorized=true;...

We already have such options syntax for browser providers' options.

  1. I would argue that we should support only Buffers and threat strings as a kind of Buffer. Yes, Node.js API works this way, but it makes harder switching from CLI to a custom runner. We went a similar way with globs and runner.src, and now this feature is in top 5 of the requested features. IMHO our API must be as convenient as the CLI.
@miherlosev

This comment has been minimized.

Copy link
Collaborator

miherlosev commented May 16, 2018

After discussing with @AndreyBelym, we introduce the following API:

Programming interface

createTestCafe (hostname, port1, port2, sslOptions)

sslOptions are nodejs https options

Command-line interface

testcafe --ssl pfx=path/to/some.pfx;rejectUnauthorized=true;...

ssl is a parameter that contains semicolon-separated options in the key-value format.

For the key, cert and pfx properties, the following processing algorithm is used:
if a property has a string type and its length is less that the MAX_PATH limit,
we interpret the value as a file path. Thus, we read the file content and replace the property value with this content.

@kirovboris Take a look please

@miherlosev

This comment has been minimized.

Copy link
Collaborator

miherlosev commented May 21, 2018

Hi @intermike

We've updated the testcafe-hammerhead dependency with changes related to the https support feature.
You can continue to develop this feature on the TestCafe side.

See an API description in #1985 (comment).
Let us know if you need any help about with our development workflow.

@intermike

This comment has been minimized.

Copy link

intermike commented May 22, 2018

Affirmative, @miherlosev.

@VasilyStrelyaev

This comment has been minimized.

Copy link
Collaborator

VasilyStrelyaev commented Jul 6, 2018

Working on docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment