mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Co-authored-by: spalger <spalger@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> # Conflicts: # test/common/services/deployment.ts # test/common/services/index.ts # test/common/services/saved_object_info.ts # test/functional/apps/visualize/index.ts
This commit is contained in:
parent
fa7dc5c9e4
commit
b601c5c3b4
19 changed files with 262 additions and 219 deletions
|
@ -139,11 +139,14 @@ export default function (/* { providerAPI } */) {
|
|||
}
|
||||
-----------
|
||||
|
||||
**Services**:::
|
||||
Services are named singleton values produced by a Service Provider. Tests and other services can retrieve service instances by asking for them by name. All functionality except the mocha API is exposed via services.
|
||||
**Service**:::
|
||||
A Service is a named singleton created using a subclass of `FtrService`. Tests and other services can retrieve service instances by asking for them by name. All functionality except the mocha API is exposed via services. When you write your own functional tests check for existing services that help with the interactions you're looking to execute, and add new services for interactions which aren't already encoded in a service.
|
||||
|
||||
**Service Providers**:::
|
||||
For legacy purposes, and for when creating a subclass of `FtrService` is inconvenient, you can also create services using a "Service Provider". These are functions which which create service instances and return them. These instances are cached and provided to tests. Currently these providers may also return a Promise for the service instance, allowing the service to do some setup work before tests run. We expect to fully deprecate and remove support for async service providers in the near future and instead require that services use the `lifecycle` service to run setup before tests. Providers which return instances of classes other than `FtrService` will likely remain supported for as long as possible.
|
||||
|
||||
**Page objects**:::
|
||||
Page objects are a special type of service that encapsulate behaviors common to a particular page or plugin. When you write your own plugin, you’ll likely want to add a page object (or several) that describes the common interactions your tests need to execute.
|
||||
Page objects are functionally equivalent to services, except they are loaded with a slightly different mechanism and generally defined separate from services. When you write your own functional tests you might want to write some of your services as Page objects, but it is not required.
|
||||
|
||||
**Test Files**:::
|
||||
The `FunctionalTestRunner`'s primary purpose is to execute test files. These files export a Test Provider that is called with a Provider API but is not expected to return a value. Instead Test Providers define a suite using https://mochajs.org/#bdd[mocha's BDD interface].
|
||||
|
|
|
@ -12,6 +12,7 @@ import { loadTracer } from '../load_tracer';
|
|||
import { createAsyncInstance, isAsyncInstance } from './async_instance';
|
||||
import { Providers } from './read_provider_spec';
|
||||
import { createVerboseInstance } from './verbose_instance';
|
||||
import { GenericFtrService } from '../../public_types';
|
||||
|
||||
export class ProviderCollection {
|
||||
private readonly instances = new Map();
|
||||
|
@ -58,12 +59,19 @@ export class ProviderCollection {
|
|||
}
|
||||
|
||||
public invokeProviderFn(provider: (args: any) => any) {
|
||||
return provider({
|
||||
const ctx = {
|
||||
getService: this.getService,
|
||||
hasService: this.hasService,
|
||||
getPageObject: this.getPageObject,
|
||||
getPageObjects: this.getPageObjects,
|
||||
});
|
||||
};
|
||||
|
||||
if (provider.prototype instanceof GenericFtrService) {
|
||||
const Constructor = (provider as any) as new (ctx: any) => any;
|
||||
return new Constructor(ctx);
|
||||
}
|
||||
|
||||
return provider(ctx);
|
||||
}
|
||||
|
||||
private findProvider(type: string, name: string) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import { Test, Suite } from './fake_mocha_types';
|
|||
|
||||
export { Lifecycle, Config, FailureMetadata };
|
||||
|
||||
interface AsyncInstance<T> {
|
||||
export interface AsyncInstance<T> {
|
||||
/**
|
||||
* Services that are initialized async are not ready before the tests execute, so you might need
|
||||
* to call `init()` and await the promise it returns before interacting with the service
|
||||
|
@ -39,7 +39,11 @@ export type ProvidedType<T extends (...args: any[]) => any> = MaybeAsyncInstance
|
|||
* promise types into the async instances that other providers will receive.
|
||||
*/
|
||||
type ProvidedTypeMap<T extends {}> = {
|
||||
[K in keyof T]: T[K] extends (...args: any[]) => any ? ProvidedType<T[K]> : unknown;
|
||||
[K in keyof T]: T[K] extends new (...args: any[]) => infer X
|
||||
? X
|
||||
: T[K] extends (...args: any[]) => any
|
||||
? ProvidedType<T[K]>
|
||||
: unknown;
|
||||
};
|
||||
|
||||
export interface GenericFtrProviderContext<
|
||||
|
@ -84,6 +88,10 @@ export interface GenericFtrProviderContext<
|
|||
loadTestFile(path: string): void;
|
||||
}
|
||||
|
||||
export class GenericFtrService<ProviderContext extends GenericFtrProviderContext<any, any>> {
|
||||
constructor(protected readonly ctx: ProviderContext) {}
|
||||
}
|
||||
|
||||
export interface FtrConfigProviderContext {
|
||||
log: ToolingLog;
|
||||
readConfigFile(path: string): Promise<Config>;
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { GenericFtrProviderContext } from '@kbn/test';
|
||||
import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test';
|
||||
|
||||
import { services } from './services';
|
||||
|
||||
export type FtrProviderContext = GenericFtrProviderContext<typeof services, {}>;
|
||||
export class FtrService extends GenericFtrService<FtrProviderContext> {}
|
|
@ -10,47 +10,45 @@ import { get } from 'lodash';
|
|||
import fetch from 'node-fetch';
|
||||
import { getUrl } from '@kbn/test';
|
||||
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
import { FtrService } from '../ftr_provider_context';
|
||||
|
||||
export function DeploymentProvider({ getService }: FtrProviderContext) {
|
||||
const config = getService('config');
|
||||
export class DeploymentService extends FtrService {
|
||||
private readonly config = this.ctx.getService('config');
|
||||
|
||||
return {
|
||||
/**
|
||||
* Returns Kibana host URL
|
||||
*/
|
||||
getHostPort() {
|
||||
return getUrl.baseUrl(config.get('servers.kibana'));
|
||||
},
|
||||
/**
|
||||
* Returns Kibana host URL
|
||||
*/
|
||||
getHostPort() {
|
||||
return getUrl.baseUrl(this.config.get('servers.kibana'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ES host URL
|
||||
*/
|
||||
getEsHostPort() {
|
||||
return getUrl.baseUrl(config.get('servers.elasticsearch'));
|
||||
},
|
||||
/**
|
||||
* Returns ES host URL
|
||||
*/
|
||||
getEsHostPort() {
|
||||
return getUrl.baseUrl(this.config.get('servers.elasticsearch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to detect an OSS licensed Kibana
|
||||
* Useful for functional testing in cloud environment
|
||||
*/
|
||||
async isOss() {
|
||||
return config.get('kbnTestServer.serverArgs').indexOf('--oss') > -1;
|
||||
},
|
||||
/**
|
||||
* Helper to detect an OSS licensed Kibana
|
||||
* Useful for functional testing in cloud environment
|
||||
*/
|
||||
async isOss() {
|
||||
return this.config.get('kbnTestServer.serverArgs').indexOf('--oss') > -1;
|
||||
}
|
||||
|
||||
async isCloud(): Promise<boolean> {
|
||||
const baseUrl = this.getHostPort();
|
||||
const username = config.get('servers.kibana.username');
|
||||
const password = config.get('servers.kibana.password');
|
||||
const response = await fetch(baseUrl + '/api/stats?extended', {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
return get(data, 'usage.cloud.is_cloud_enabled', false);
|
||||
},
|
||||
};
|
||||
async isCloud(): Promise<boolean> {
|
||||
const baseUrl = this.getHostPort();
|
||||
const username = this.config.get('servers.kibana.username');
|
||||
const password = this.config.get('servers.kibana.password');
|
||||
const response = await fetch(baseUrl + '/api/stats?extended', {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
return get(data, 'usage.cloud.is_cloud_enabled', false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,24 +6,24 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { DeploymentProvider } from './deployment';
|
||||
import { DeploymentService } from './deployment';
|
||||
import { LegacyEsProvider } from './legacy_es';
|
||||
import { ElasticsearchProvider } from './elasticsearch';
|
||||
import { EsArchiverProvider } from './es_archiver';
|
||||
import { KibanaServerProvider } from './kibana_server';
|
||||
import { RetryProvider } from './retry';
|
||||
import { RandomnessProvider } from './randomness';
|
||||
import { RetryService } from './retry';
|
||||
import { RandomnessService } from './randomness';
|
||||
import { SecurityServiceProvider } from './security';
|
||||
import { EsDeleteAllIndicesProvider } from './es_delete_all_indices';
|
||||
|
||||
export const services = {
|
||||
deployment: DeploymentProvider,
|
||||
deployment: DeploymentService,
|
||||
legacyEs: LegacyEsProvider,
|
||||
es: ElasticsearchProvider,
|
||||
esArchiver: EsArchiverProvider,
|
||||
kibanaServer: KibanaServerProvider,
|
||||
retry: RetryProvider,
|
||||
randomness: RandomnessProvider,
|
||||
retry: RetryService,
|
||||
randomness: RandomnessService,
|
||||
security: SecurityServiceProvider,
|
||||
esDeleteAllIndices: EsDeleteAllIndicesProvider,
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ import { KbnClient } from '@kbn/test';
|
|||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export function KibanaServerProvider({ getService }: FtrProviderContext) {
|
||||
export function KibanaServerProvider({ getService }: FtrProviderContext): KbnClient {
|
||||
const log = getService('log');
|
||||
const config = getService('config');
|
||||
const lifecycle = getService('lifecycle');
|
||||
|
|
|
@ -7,8 +7,20 @@
|
|||
*/
|
||||
|
||||
import Chance from 'chance';
|
||||
import { ToolingLog } from '@kbn/dev-utils';
|
||||
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
import { FtrService } from '../ftr_provider_context';
|
||||
|
||||
let __CACHED_SEED__: number | undefined;
|
||||
function getSeed(log: ToolingLog) {
|
||||
if (__CACHED_SEED__ !== undefined) {
|
||||
return __CACHED_SEED__;
|
||||
}
|
||||
|
||||
__CACHED_SEED__ = Date.now();
|
||||
log.debug('randomness seed: %j', __CACHED_SEED__);
|
||||
return __CACHED_SEED__;
|
||||
}
|
||||
|
||||
interface CharOptions {
|
||||
pool?: string;
|
||||
|
@ -27,52 +39,45 @@ interface NumberOptions {
|
|||
max?: number;
|
||||
}
|
||||
|
||||
export function RandomnessProvider({ getService }: FtrProviderContext) {
|
||||
const log = getService('log');
|
||||
export class RandomnessService extends FtrService {
|
||||
private readonly chance = new Chance(getSeed(this.ctx.getService('log')));
|
||||
|
||||
const seed = Date.now();
|
||||
log.debug('randomness seed: %j', seed);
|
||||
/**
|
||||
* Generate a random natural number
|
||||
*
|
||||
* range: 0 to 9007199254740991
|
||||
*
|
||||
*/
|
||||
naturalNumber(options?: NumberOptions) {
|
||||
return this.chance.natural(options);
|
||||
}
|
||||
|
||||
const chance = new Chance(seed);
|
||||
/**
|
||||
* Generate a random integer
|
||||
*/
|
||||
integer(options?: NumberOptions) {
|
||||
return this.chance.integer(options);
|
||||
}
|
||||
|
||||
return new (class RandomnessService {
|
||||
/**
|
||||
* Generate a random natural number
|
||||
*
|
||||
* range: 0 to 9007199254740991
|
||||
*
|
||||
*/
|
||||
naturalNumber(options?: NumberOptions) {
|
||||
return chance.natural(options);
|
||||
}
|
||||
/**
|
||||
* Generate a random number, defaults to at least 4 and no more than 8 syllables
|
||||
*/
|
||||
word(options: { syllables?: number } = {}) {
|
||||
const { syllables = this.naturalNumber({ min: 4, max: 8 }) } = options;
|
||||
|
||||
/**
|
||||
* Generate a random integer
|
||||
*/
|
||||
integer(options?: NumberOptions) {
|
||||
return chance.integer(options);
|
||||
}
|
||||
return this.chance.word({
|
||||
syllables,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random number, defaults to at least 4 and no more than 8 syllables
|
||||
*/
|
||||
word(options: { syllables?: number } = {}) {
|
||||
const { syllables = this.naturalNumber({ min: 4, max: 8 }) } = options;
|
||||
|
||||
return chance.word({
|
||||
syllables,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random string, defaults to at least 8 and no more than 15 alpha-numeric characters
|
||||
*/
|
||||
string(options: StringOptions = {}) {
|
||||
return chance.string({
|
||||
length: this.naturalNumber({ min: 8, max: 15 }),
|
||||
...(options.pool === 'undefined' ? { alpha: true, numeric: true, symbols: false } : {}),
|
||||
...options,
|
||||
});
|
||||
}
|
||||
})();
|
||||
/**
|
||||
* Generate a random string, defaults to at least 8 and no more than 15 alpha-numeric characters
|
||||
*/
|
||||
string(options: StringOptions = {}) {
|
||||
return this.chance.string({
|
||||
length: this.naturalNumber({ min: 8, max: 15 }),
|
||||
...(options.pool === 'undefined' ? { alpha: true, numeric: true, symbols: false } : {}),
|
||||
...options,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { RetryProvider } from './retry';
|
||||
export { RetryService } from './retry';
|
||||
|
|
|
@ -6,64 +6,62 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { FtrService } from '../../ftr_provider_context';
|
||||
import { retryForSuccess } from './retry_for_success';
|
||||
import { retryForTruthy } from './retry_for_truthy';
|
||||
|
||||
export function RetryProvider({ getService }: FtrProviderContext) {
|
||||
const config = getService('config');
|
||||
const log = getService('log');
|
||||
export class RetryService extends FtrService {
|
||||
private readonly config = this.ctx.getService('config');
|
||||
private readonly log = this.ctx.getService('log');
|
||||
|
||||
return new (class Retry {
|
||||
public async tryForTime<T>(
|
||||
timeout: number,
|
||||
block: () => Promise<T>,
|
||||
onFailureBlock?: () => Promise<T>
|
||||
) {
|
||||
return await retryForSuccess(log, {
|
||||
timeout,
|
||||
methodName: 'retry.tryForTime',
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
public async tryForTime<T>(
|
||||
timeout: number,
|
||||
block: () => Promise<T>,
|
||||
onFailureBlock?: () => Promise<T>
|
||||
) {
|
||||
return await retryForSuccess(this.log, {
|
||||
timeout,
|
||||
methodName: 'retry.tryForTime',
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
|
||||
public async try<T>(block: () => Promise<T>, onFailureBlock?: () => Promise<T>) {
|
||||
return await retryForSuccess(log, {
|
||||
timeout: config.get('timeouts.try'),
|
||||
methodName: 'retry.try',
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
public async try<T>(block: () => Promise<T>, onFailureBlock?: () => Promise<T>) {
|
||||
return await retryForSuccess(this.log, {
|
||||
timeout: this.config.get('timeouts.try'),
|
||||
methodName: 'retry.try',
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
|
||||
public async waitForWithTimeout(
|
||||
description: string,
|
||||
timeout: number,
|
||||
block: () => Promise<boolean>,
|
||||
onFailureBlock?: () => Promise<any>
|
||||
) {
|
||||
await retryForTruthy(log, {
|
||||
timeout,
|
||||
methodName: 'retry.waitForWithTimeout',
|
||||
description,
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
public async waitForWithTimeout(
|
||||
description: string,
|
||||
timeout: number,
|
||||
block: () => Promise<boolean>,
|
||||
onFailureBlock?: () => Promise<any>
|
||||
) {
|
||||
await retryForTruthy(this.log, {
|
||||
timeout,
|
||||
methodName: 'retry.waitForWithTimeout',
|
||||
description,
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
|
||||
public async waitFor(
|
||||
description: string,
|
||||
block: () => Promise<boolean>,
|
||||
onFailureBlock?: () => Promise<any>
|
||||
) {
|
||||
await retryForTruthy(log, {
|
||||
timeout: config.get('timeouts.waitFor'),
|
||||
methodName: 'retry.waitFor',
|
||||
description,
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
})();
|
||||
public async waitFor(
|
||||
description: string,
|
||||
block: () => Promise<boolean>,
|
||||
onFailureBlock?: () => Promise<any>
|
||||
) {
|
||||
await retryForTruthy(this.log, {
|
||||
timeout: this.config.get('timeouts.waitFor'),
|
||||
methodName: 'retry.waitFor',
|
||||
description,
|
||||
block,
|
||||
onFailureBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,23 +10,27 @@ import { Role } from './role';
|
|||
import { User } from './user';
|
||||
import { RoleMappings } from './role_mappings';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { createTestUserService, TestUserSupertestProvider } from './test_user';
|
||||
import { createTestUserService, TestUserSupertestProvider, TestUser } from './test_user';
|
||||
|
||||
export async function SecurityServiceProvider(context: FtrProviderContext) {
|
||||
const { getService } = context;
|
||||
const log = getService('log');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
export class SecurityService {
|
||||
constructor(
|
||||
public readonly roleMappings: RoleMappings,
|
||||
public readonly testUser: TestUser,
|
||||
public readonly role: Role,
|
||||
public readonly user: User,
|
||||
public readonly testUserSupertest: ReturnType<typeof TestUserSupertestProvider>
|
||||
) {}
|
||||
}
|
||||
|
||||
export async function SecurityServiceProvider(ctx: FtrProviderContext) {
|
||||
const log = ctx.getService('log');
|
||||
const kibanaServer = ctx.getService('kibanaServer');
|
||||
|
||||
const role = new Role(log, kibanaServer);
|
||||
const user = new User(log, kibanaServer);
|
||||
const testUser = await createTestUserService(role, user, context);
|
||||
const testUserSupertest = TestUserSupertestProvider(context);
|
||||
const testUser = await createTestUserService(ctx, role, user);
|
||||
const testUserSupertest = TestUserSupertestProvider(ctx);
|
||||
const roleMappings = new RoleMappings(log, kibanaServer);
|
||||
|
||||
return new (class SecurityService {
|
||||
roleMappings = new RoleMappings(log, kibanaServer);
|
||||
testUser = testUser;
|
||||
role = role;
|
||||
user = user;
|
||||
testUserSupertest = testUserSupertest;
|
||||
})();
|
||||
return new SecurityService(roleMappings, testUser, role, user, testUserSupertest);
|
||||
}
|
||||
|
|
|
@ -11,41 +11,84 @@ import supertestAsPromised from 'supertest-as-promised';
|
|||
|
||||
import { Role } from './role';
|
||||
import { User } from './user';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { FtrService, FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { Browser } from '../../../functional/services/common';
|
||||
import { TestSubjects } from '../../../functional/services/common';
|
||||
|
||||
const TEST_USER_NAME = 'test_user';
|
||||
const TEST_USER_PASSWORD = 'changeme';
|
||||
|
||||
export async function createTestUserService(
|
||||
role: Role,
|
||||
user: User,
|
||||
{ getService, hasService }: FtrProviderContext
|
||||
) {
|
||||
const log = getService('log');
|
||||
const config = getService('config');
|
||||
// @ts-ignore browser service is not normally available in common.
|
||||
const browser: Browser | void = hasService('browser') && getService('browser');
|
||||
const testSubjects: TestSubjects | undefined =
|
||||
export class TestUser extends FtrService {
|
||||
private readonly config = this.ctx.getService('config');
|
||||
private readonly log = this.ctx.getService('log');
|
||||
|
||||
private readonly browser: Browser | void =
|
||||
// browser service is not normally available in common.
|
||||
this.ctx.hasService('browser') ? (this.ctx.getService('browser' as any) as Browser) : undefined;
|
||||
|
||||
private readonly testSubjects: TestSubjects | undefined =
|
||||
// testSubject service is not normally available in common.
|
||||
hasService('testSubjects') ? (getService('testSubjects' as any) as TestSubjects) : undefined;
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
this.ctx.hasService('testSubjects')
|
||||
? (this.ctx.getService('testSubjects' as any) as TestSubjects)
|
||||
: undefined;
|
||||
|
||||
constructor(
|
||||
ctx: FtrProviderContext,
|
||||
private readonly enabled: boolean,
|
||||
private readonly user: User
|
||||
) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
async restoreDefaults(shouldRefreshBrowser: boolean = true) {
|
||||
if (this.enabled) {
|
||||
await this.setRoles(this.config.get('security.defaultRoles'), shouldRefreshBrowser);
|
||||
}
|
||||
}
|
||||
|
||||
async setRoles(roles: string[], shouldRefreshBrowser: boolean = true) {
|
||||
if (this.enabled) {
|
||||
this.log.debug(`set roles = ${roles}`);
|
||||
await this.user.create(TEST_USER_NAME, {
|
||||
password: TEST_USER_PASSWORD,
|
||||
roles,
|
||||
full_name: 'test user',
|
||||
});
|
||||
|
||||
if (this.browser && this.testSubjects && shouldRefreshBrowser) {
|
||||
if (await this.testSubjects.exists('kibanaChrome', { allowHidden: true })) {
|
||||
await this.browser.refresh();
|
||||
// accept alert if it pops up
|
||||
const alert = await this.browser.getAlert();
|
||||
await alert?.accept();
|
||||
await this.testSubjects.find('kibanaChrome', this.config.get('timeouts.find') * 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function createTestUserService(ctx: FtrProviderContext, role: Role, user: User) {
|
||||
const log = ctx.getService('log');
|
||||
const config = ctx.getService('config');
|
||||
const kibanaServer = ctx.getService('kibanaServer');
|
||||
|
||||
const enabledPlugins = config.get('security.disableTestUser')
|
||||
? []
|
||||
: await kibanaServer.plugins.getEnabledIds();
|
||||
const isEnabled = () => {
|
||||
return enabledPlugins.includes('security') && !config.get('security.disableTestUser');
|
||||
};
|
||||
if (isEnabled()) {
|
||||
|
||||
const enabled = enabledPlugins.includes('security') && !config.get('security.disableTestUser');
|
||||
|
||||
if (enabled) {
|
||||
log.debug('===============creating roles and users===============');
|
||||
|
||||
// create the defined roles (need to map array to create roles)
|
||||
for (const [name, definition] of Object.entries(config.get('security.roles'))) {
|
||||
// create the defined roles (need to map array to create roles)
|
||||
await role.create(name, definition);
|
||||
}
|
||||
|
||||
// delete the test_user if present (will it error if the user doesn't exist?)
|
||||
try {
|
||||
// delete the test_user if present (will it error if the user doesn't exist?)
|
||||
await user.delete(TEST_USER_NAME);
|
||||
} catch (exception) {
|
||||
log.debug('no test user to delete');
|
||||
|
@ -60,34 +103,7 @@ export async function createTestUserService(
|
|||
});
|
||||
}
|
||||
|
||||
return new (class TestUser {
|
||||
async restoreDefaults(shouldRefreshBrowser: boolean = true) {
|
||||
if (isEnabled()) {
|
||||
await this.setRoles(config.get('security.defaultRoles'), shouldRefreshBrowser);
|
||||
}
|
||||
}
|
||||
|
||||
async setRoles(roles: string[], shouldRefreshBrowser: boolean = true) {
|
||||
if (isEnabled()) {
|
||||
log.debug(`set roles = ${roles}`);
|
||||
await user.create(TEST_USER_NAME, {
|
||||
password: TEST_USER_PASSWORD,
|
||||
roles,
|
||||
full_name: 'test user',
|
||||
});
|
||||
|
||||
if (browser && testSubjects && shouldRefreshBrowser) {
|
||||
if (await testSubjects.exists('kibanaChrome', { allowHidden: true })) {
|
||||
await browser.refresh();
|
||||
// accept alert if it pops up
|
||||
const alert = await browser.getAlert();
|
||||
await alert?.accept();
|
||||
await testSubjects.find('kibanaChrome', config.get('timeouts.find') * 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
return new TestUser(ctx, enabled, user);
|
||||
}
|
||||
|
||||
export function TestUserSupertestProvider({ getService }: FtrProviderContext) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context.d';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { UI_SETTINGS } from '../../../../src/plugins/data/common';
|
||||
|
||||
export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context.d';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import { UI_SETTINGS } from '../../../../../src/plugins/data/common';
|
||||
|
||||
export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { GenericFtrProviderContext } from '@kbn/test';
|
||||
import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test';
|
||||
|
||||
import { pageObjects } from './page_objects';
|
||||
import { services } from './services';
|
||||
|
||||
export type FtrProviderContext = GenericFtrProviderContext<typeof services, typeof pageObjects>;
|
||||
export class FtrService extends GenericFtrService<FtrProviderContext> {}
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import { FtrProviderContext } from '../ftr_provider_context.d';
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
import { WebElementWrapper } from '../services/lib/web_element_wrapper';
|
||||
|
||||
export type CommonlyUsed =
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../ftr_provider_context.d';
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
import { WebElementWrapper } from '../services/lib/web_element_wrapper';
|
||||
|
||||
export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrProviderContext) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context.d';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
||||
const browser = getService('browser');
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { GenericFtrProviderContext } from '@kbn/test';
|
||||
import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test';
|
||||
|
||||
import { pageObjects } from './page_objects';
|
||||
import { services } from './services';
|
||||
|
||||
export type FtrProviderContext = GenericFtrProviderContext<typeof services, typeof pageObjects>;
|
||||
export class FtrService extends GenericFtrService<FtrProviderContext> {}
|
Loading…
Add table
Add a link
Reference in a new issue