1 | /*
|
2 | * Copyright (c) 2015, Groupon, Inc.
|
3 | * All rights reserved.
|
4 | *
|
5 | * Redistribution and use in source and binary forms, with or without
|
6 | * modification, are permitted provided that the following conditions
|
7 | * are met:
|
8 | *
|
9 | * Redistributions of source code must retain the above copyright notice,
|
10 | * this list of conditions and the following disclaimer.
|
11 | *
|
12 | * Redistributions in binary form must reproduce the above copyright
|
13 | * notice, this list of conditions and the following disclaimer in the
|
14 | * documentation and/or other materials provided with the distribution.
|
15 | *
|
16 | * Neither the name of GROUPON nor the names of its contributors may be
|
17 | * used to endorse or promote products derived from this software without
|
18 | * specific prior written permission.
|
19 | *
|
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
21 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31 | */
|
32 |
|
33 | ;
|
34 |
|
35 | const debug = require('debug')('testium-core:driver-factory');
|
36 | const _ = require('lodash');
|
37 | const Bluebird = require('bluebird');
|
38 |
|
39 | function loadDriver(driverType) {
|
40 | debug('Loading driver', driverType);
|
41 | // eslint-disable-next-line import/no-dynamic-require
|
42 | return require(`testium-driver-${driverType}`);
|
43 | }
|
44 |
|
45 | function autoloadDriver(driverType) {
|
46 | if (driverType === false) {
|
47 | debug('Driver creation disabled');
|
48 | return _.identity;
|
49 | }
|
50 |
|
51 | switch (typeof driverType) {
|
52 | case 'function':
|
53 | return driverType;
|
54 |
|
55 | case 'string':
|
56 | return loadDriver(driverType);
|
57 |
|
58 | default:
|
59 | throw new Error(`Invalid driver type: ${driverType}`);
|
60 | }
|
61 | }
|
62 |
|
63 | // We want to memo based on strict equality, not based on string-value
|
64 | function strictEqualityResolver() {
|
65 | const knownValues = [];
|
66 | function resolveMemoKey(value) {
|
67 | if (knownValues.indexOf(value) === -1) {
|
68 | knownValues.push(value);
|
69 | }
|
70 | return `${_.indexOf(knownValues, value)}`;
|
71 | }
|
72 | return resolveMemoKey;
|
73 | }
|
74 |
|
75 | const getDriverFactory = _.memoize(createDriver => {
|
76 | const factory = {
|
77 | create: createDriver,
|
78 | // Exposed so that we can tell if priming is needed
|
79 | instance: null,
|
80 | once: function createDriverOnce(testium) {
|
81 | if (factory.instance) {
|
82 | testium.browser = factory.instance;
|
83 | return Bluebird.resolve(testium);
|
84 | }
|
85 |
|
86 | return Bluebird.resolve(createDriver(testium)).then(() => {
|
87 | factory.instance = testium.browser;
|
88 | return testium;
|
89 | });
|
90 | },
|
91 | };
|
92 | return factory;
|
93 | }, strictEqualityResolver());
|
94 |
|
95 | function resolveDriver(driverType) {
|
96 | const createDriver = autoloadDriver(driverType);
|
97 | return getDriverFactory(createDriver);
|
98 | }
|
99 | module.exports = resolveDriver;
|