diff --git a/src/core_plugins/getting_started/index.js b/src/core_plugins/getting_started/index.js new file mode 100644 index 00000000000000..61dd97ba56408b --- /dev/null +++ b/src/core_plugins/getting_started/index.js @@ -0,0 +1,8 @@ +export default function (kibana) { + + return new kibana.Plugin({ + uiExports: { + managementSections: ['plugins/getting_started'] + } + }); +} diff --git a/src/core_plugins/getting_started/package.json b/src/core_plugins/getting_started/package.json new file mode 100644 index 00000000000000..da2e9c14b8d29d --- /dev/null +++ b/src/core_plugins/getting_started/package.json @@ -0,0 +1,4 @@ +{ + "name": "getting_started", + "version": "kibana" +} diff --git a/src/core_plugins/getting_started/public/components/getting_started/getting_started.html b/src/core_plugins/getting_started/public/components/getting_started/getting_started.html new file mode 100644 index 00000000000000..e846238eeeb091 --- /dev/null +++ b/src/core_plugins/getting_started/public/components/getting_started/getting_started.html @@ -0,0 +1,179 @@ +
+ +
+ +
+ +
+

+ Welcome to Kibana +

+
+ + + +
+ +
+ +
+
+
+
+
+

+ First, add your data +

+
+ +
+
+ + +
+
+
+ + +
+ +
+
+
+

+ Visualize and explore +

+
+ +
+
+ +
+
+
+ + +
+ +
+
+
+

+ Manage and monitor +

+
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
+
+

Just want to see what Kibana is capable of doing?

+
+ + +
+
+ +
+

+ Kibana documentation + is always available to help. +

+
+
diff --git a/src/core_plugins/getting_started/public/components/getting_started/getting_started.js b/src/core_plugins/getting_started/public/components/getting_started/getting_started.js new file mode 100644 index 00000000000000..1ec9c774d445fe --- /dev/null +++ b/src/core_plugins/getting_started/public/components/getting_started/getting_started.js @@ -0,0 +1,65 @@ +import { uiModules } from 'ui/modules'; +import uiChrome from 'ui/chrome'; +import 'ui/getting_started/opt_out_directive'; +import { GettingStartedRegistryProvider } from 'ui/getting_started/registry'; +import { GETTING_STARTED_REGISTRY_TYPES } from 'ui/getting_started/constants'; +import { hasOptedOutOfGettingStarted } from 'ui/getting_started/opt_out_helpers'; +import { documentationLinks } from 'ui/documentation_links'; + +import kibanaLogo from 'ui/images/logo-kibana-small.svg'; +import beatsLogo from 'ui/images/logo-beats-small.svg'; +import logstashLogo from 'ui/images/logo-logstash-small.svg'; +import dashboardIcon from 'ui/images/icon-dashboard.svg'; +import shieldIcon from 'ui/images/icon-shield.svg'; + +import template from './getting_started.html'; +import './getting_started.less'; +import '../injected_items'; + +const app = uiModules.get('kibana'); + +app.directive('gettingStarted', function ($injector) { + const Private = $injector.get('Private'); + + const registry = Private(GettingStartedRegistryProvider); + + return { + restrict: 'E', + template: template, + scope: { + }, + bindToController: true, + controllerAs: 'gettingStarted', + controller: class GettingStartedController { + constructor() { + if (this.hasOptedOut()) { + uiChrome.setVisible(true); + } else { + uiChrome.setVisible(false); + } + + const registeredTopMessages = registry.byType[GETTING_STARTED_REGISTRY_TYPES.TOP_MESSAGE] || []; + this.topMessages = registeredTopMessages.map(item => item.template); + + const registeredManageAndMonitorMessages = registry.byType[GETTING_STARTED_REGISTRY_TYPES.MANAGE_AND_MONITOR_MESSAGE] || []; + this.manageAndMonitorMessages = registeredManageAndMonitorMessages.map(item => item.template); + + this.imageUrls = { + kibanaLogo, + beatsLogo, + logstashLogo, + dashboardIcon, + shieldIcon + }; + + this.documentationLinks = documentationLinks; + } + + hasManageAndMonitorMessages = () => { + return this.manageAndMonitorMessages.length > 0; + } + + hasOptedOut = hasOptedOutOfGettingStarted; + } + }; +}); diff --git a/src/core_plugins/getting_started/public/components/getting_started/getting_started.less b/src/core_plugins/getting_started/public/components/getting_started/getting_started.less new file mode 100644 index 00000000000000..8a3cbef7744e6f --- /dev/null +++ b/src/core_plugins/getting_started/public/components/getting_started/getting_started.less @@ -0,0 +1,65 @@ +.gettingStartedContent { + display: flex; + flex-direction: column; + align-items: center; + padding-top: 0; +} + +.gettingStartedOptOutContent { + position: absolute; + top: 20px; + right: 30px; +} + +.gettingStartedWelcome { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 200px; + width: 100%; + background-color: #f7f7f7; +} + +.gettingStartedTitle { + transform: translateY(10px); +} + +.gettingStartedLogo { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + border: 1px solid #D7DBDD; + width: 100px; + height: 100px; + border-radius: 100%; + + background-color: #ffffff; + + transform: translateY(-60px); +} + +.gettingStartedLogoRow { + display: flex; + flex-direction: row; + justify-content: center; +} + +.gettingStartedLogoRow__logo { + height: 80px; + + & + & { + margin-left: 40px; + } +} + +.gettingStartedCard__descriptionText { + margin-top: 32px; + margin-bottom: 32px; +} + +.gettingStartedCard { + width: 340px; +} \ No newline at end of file diff --git a/src/core_plugins/getting_started/public/components/getting_started/index.js b/src/core_plugins/getting_started/public/components/getting_started/index.js new file mode 100644 index 00000000000000..730b88e595f36f --- /dev/null +++ b/src/core_plugins/getting_started/public/components/getting_started/index.js @@ -0,0 +1 @@ +import './getting_started'; \ No newline at end of file diff --git a/src/core_plugins/getting_started/public/components/injected_items/index.js b/src/core_plugins/getting_started/public/components/injected_items/index.js new file mode 100644 index 00000000000000..3f4523d33f0763 --- /dev/null +++ b/src/core_plugins/getting_started/public/components/injected_items/index.js @@ -0,0 +1 @@ +import './injected_items'; diff --git a/src/core_plugins/getting_started/public/components/injected_items/injected_items.html b/src/core_plugins/getting_started/public/components/injected_items/injected_items.html new file mode 100644 index 00000000000000..7c89b545c5ac0a --- /dev/null +++ b/src/core_plugins/getting_started/public/components/injected_items/injected_items.html @@ -0,0 +1 @@ +
diff --git a/src/core_plugins/getting_started/public/components/injected_items/injected_items.js b/src/core_plugins/getting_started/public/components/injected_items/injected_items.js new file mode 100644 index 00000000000000..97260591a1c937 --- /dev/null +++ b/src/core_plugins/getting_started/public/components/injected_items/injected_items.js @@ -0,0 +1,38 @@ +import { isArray } from 'lodash'; +import { uiModules } from 'ui/modules'; +import angular from 'angular'; + +import template from './injected_items.html'; +import './injected_items.less'; + +function makeAngularParseableExpression(item) { + return `
${item} 
`; +} + +const app = uiModules.get('kibana'); + +app.directive('injectedItems', function ($injector) { + const $compile = $injector.get('$compile'); + + return { + restrict: 'E', + replace: true, + template: template, + scope: { + items: '=' + }, + link: ($scope, $el) => { + const items = $scope.items; + + if (isArray(items) && items.length > 0) { + items.forEach(item => { + // Compile itemHtml with current $scope and append it into the container DOM element. + // We do this because we want to dynamically inject content (strings) into the DOM. This content + // may contain Angular directives so it must first be $compiled with the current $scope. + const itemHtml = $compile(makeAngularParseableExpression(item))($scope); + angular.element($el).append(itemHtml); + }); + } + } + }; +}); diff --git a/src/core_plugins/getting_started/public/components/injected_items/injected_items.less b/src/core_plugins/getting_started/public/components/injected_items/injected_items.less new file mode 100644 index 00000000000000..3102c5057d6fa7 --- /dev/null +++ b/src/core_plugins/getting_started/public/components/injected_items/injected_items.less @@ -0,0 +1,3 @@ +.injectedItems__item { + display: inline; +} diff --git a/src/core_plugins/getting_started/public/getting_started_route.html b/src/core_plugins/getting_started/public/getting_started_route.html new file mode 100644 index 00000000000000..870a1824b37903 --- /dev/null +++ b/src/core_plugins/getting_started/public/getting_started_route.html @@ -0,0 +1 @@ + diff --git a/src/core_plugins/getting_started/public/getting_started_route.js b/src/core_plugins/getting_started/public/getting_started_route.js new file mode 100644 index 00000000000000..46db8edf18ee83 --- /dev/null +++ b/src/core_plugins/getting_started/public/getting_started_route.js @@ -0,0 +1,14 @@ +import routes from 'ui/routes'; +import template from './getting_started_route.html'; +import './components/getting_started'; +import { GETTING_STARTED_ROUTE } from './lib/constants'; + +routes +.when(GETTING_STARTED_ROUTE, { + template: template, + controllerAs: 'gettingStartedRoute', + controller: class GettingStartedRouteController { + constructor() { + } + } +}); diff --git a/src/core_plugins/getting_started/public/index.js b/src/core_plugins/getting_started/public/index.js new file mode 100644 index 00000000000000..7ae2fd452e9411 --- /dev/null +++ b/src/core_plugins/getting_started/public/index.js @@ -0,0 +1,3 @@ +import './lib/add_setup_work'; +import './lib/register_management_section'; +import './getting_started_route'; diff --git a/src/core_plugins/getting_started/public/lib/add_setup_work.js b/src/core_plugins/getting_started/public/lib/add_setup_work.js new file mode 100644 index 00000000000000..028fe8e6f81592 --- /dev/null +++ b/src/core_plugins/getting_started/public/lib/add_setup_work.js @@ -0,0 +1,81 @@ +import { get } from 'lodash'; +import uiRoutes from 'ui/routes'; +import uiChrome from 'ui/chrome'; +import KbnUrlProvider from 'ui/url'; +import { Notifier } from 'ui/notify/notifier'; +import { IndexPatternsGetIdsProvider } from 'ui/index_patterns/_get_ids'; +import { hasOptedOutOfGettingStarted, optOutOfGettingStarted } from 'ui/getting_started/opt_out_helpers'; + +import { + GETTING_STARTED_ROUTE, + CREATE_INDEX_PATTERN_ROUTE +} from './constants'; + +uiRoutes + .addSetupWork(function gettingStartedGateCheck(Private, $injector) { + const getIds = Private(IndexPatternsGetIdsProvider); + const kbnUrl = Private(KbnUrlProvider); + const config = $injector.get('config'); + const $route = $injector.get('$route'); + + const currentRoute = get($route, 'current.$$route'); + + return getIds() + .then(indexPatterns => { + const indexPatternsExist = Array.isArray(indexPatterns) && indexPatterns.length > 0; + const isOnGettingStartedPage = get(currentRoute, 'originalPath') === GETTING_STARTED_ROUTE; + + if (indexPatternsExist) { + + // The user need not see the Getting Started page, so opt them out of it + optOutOfGettingStarted(); + + // Some routes require a default index pattern to be present. If we're + // NOT on such a route, there's nothing more to do; send the user on their way + if (!currentRoute.requireDefaultIndex) { + return; + } + + // Otherwise, check if we have a default index pattern + let defaultIndexPattern = config.get('defaultIndex'); + + // If we don't have an default index pattern, make the first index pattern the + // default one + if (!Boolean(defaultIndexPattern)) { + defaultIndexPattern = indexPatterns[0]; + config.set('defaultIndex', defaultIndexPattern); + } + + // At this point, we have a default index pattern and are all set! + return; + } + + // At this point, no index patterns exist. + + // If the user has explicitly opted out of the Getting Started page + if (hasOptedOutOfGettingStarted()) { + + // Some routes require a default index pattern to be present. If we're + // NOT on such a route, there's nothing more to do; send the user on their way + if (!currentRoute.requireDefaultIndex) { + return; + } + + // Otherwise, redirect the user to the index pattern creation page with + // a notification about creating an index pattern + const notify = new Notifier({ + location: 'Index Patterns' + }); + notify.error('Please create a new index pattern'); + kbnUrl.change(CREATE_INDEX_PATTERN_ROUTE); + return; + } + + // Redirect the user to the Getting Started page (unless they are on it already) + if (!isOnGettingStartedPage) { + uiChrome.setVisible(false); + kbnUrl.change(GETTING_STARTED_ROUTE); + return; + } + }); + }); \ No newline at end of file diff --git a/src/core_plugins/getting_started/public/lib/constants.js b/src/core_plugins/getting_started/public/lib/constants.js new file mode 100644 index 00000000000000..2764ef2570208a --- /dev/null +++ b/src/core_plugins/getting_started/public/lib/constants.js @@ -0,0 +1,2 @@ +export const GETTING_STARTED_ROUTE = '/management/kibana/getting_started'; +export const CREATE_INDEX_PATTERN_ROUTE = '/management/kibana/index'; \ No newline at end of file diff --git a/src/core_plugins/getting_started/public/lib/register_management_section.js b/src/core_plugins/getting_started/public/lib/register_management_section.js new file mode 100644 index 00000000000000..f7759164ac16ac --- /dev/null +++ b/src/core_plugins/getting_started/public/lib/register_management_section.js @@ -0,0 +1,8 @@ +import { management } from 'ui/management'; +import { GETTING_STARTED_ROUTE } from './constants'; + +management.getSection('kibana').register('getting_started', { + display: 'Getting Started', + order: 50, + url: `#${GETTING_STARTED_ROUTE}` +}); diff --git a/src/core_plugins/kibana/public/management/index.js b/src/core_plugins/kibana/public/management/index.js index 391d70fb9193b2..91bd1dc7eede50 100644 --- a/src/core_plugins/kibana/public/management/index.js +++ b/src/core_plugins/kibana/public/management/index.js @@ -19,10 +19,6 @@ uiRoutes redirectTo: '/management' }); -require('ui/index_patterns/route_setup/load_default')({ - whenMissingRedirectTo: '/management/kibana/index' -}); - uiModules .get('apps/management') .directive('kbnManagementApp', function (Private, $location, timefilter, buildNum, buildSha) { diff --git a/src/ui/public/documentation_links/documentation_links.js b/src/ui/public/documentation_links/documentation_links.js index 2b49f38e9cdf05..dbb7038f4ef7b5 100644 --- a/src/ui/public/documentation_links/documentation_links.js +++ b/src/ui/public/documentation_links/documentation_links.js @@ -7,6 +7,18 @@ const urlVersion = `${major}.${minor}`; const baseUrl = 'https://www.elastic.co/'; export const documentationLinks = { + elasticsearch: { + docs: `${baseUrl}guide/en/elasticsearch/reference/current` + }, + beats: { + docs: `${baseUrl}guide/en/beats/libbeat/current` + }, + logstash: { + docs: `${baseUrl}guide/en/logstash/current` + }, + kibana: { + docs: `${baseUrl}guide/en/kibana/current` + }, filebeat: { installation: `${baseUrl}guide/en/beats/filebeat/${urlVersion}/filebeat-installation.html`, configuration: `${baseUrl}guide/en/beats/filebeat/${urlVersion}/filebeat-configuration.html`, @@ -25,5 +37,7 @@ export const documentationLinks = { }, query: { luceneQuerySyntax: `${baseUrl}guide/en/elasticsearch/reference/${urlVersion}/query-dsl-query-string-query.html#query-string-syntax` - } + }, + demoSite: 'http://demo.elastic.co', + gettingStarted: `${baseUrl}products/kibana/getting-started-link` }; diff --git a/src/ui/public/getting_started/constants.js b/src/ui/public/getting_started/constants.js new file mode 100644 index 00000000000000..a1b839d00ed670 --- /dev/null +++ b/src/ui/public/getting_started/constants.js @@ -0,0 +1,6 @@ +export const GETTING_STARTED_OPT_OUT_FLAG = 'kibana.isGettingStartedOptedOut'; + +export const GETTING_STARTED_REGISTRY_TYPES = { + TOP_MESSAGE: 'topMessage', + MANAGE_AND_MONITOR_MESSAGE: 'monitorAndManageMessage' +}; \ No newline at end of file diff --git a/src/ui/public/getting_started/opt_out_directive.js b/src/ui/public/getting_started/opt_out_directive.js new file mode 100644 index 00000000000000..2b5db918393006 --- /dev/null +++ b/src/ui/public/getting_started/opt_out_directive.js @@ -0,0 +1,14 @@ +import { uiModules } from 'ui/modules'; +import { optOutOfGettingStarted } from './opt_out_helpers'; + +const app = uiModules.get('kibana'); +app.directive('kbnGettingStartedOptOut', () => { + return { + restrict: 'A', + link: (scope, element) => { + element.on('click', () => { + optOutOfGettingStarted(); + }); + } + }; +}); diff --git a/src/ui/public/getting_started/opt_out_helpers.js b/src/ui/public/getting_started/opt_out_helpers.js new file mode 100644 index 00000000000000..e6cd8320f0ffe2 --- /dev/null +++ b/src/ui/public/getting_started/opt_out_helpers.js @@ -0,0 +1,11 @@ +import uiChrome from 'ui/chrome'; +import { GETTING_STARTED_OPT_OUT_FLAG } from './constants'; + +export function hasOptedOutOfGettingStarted() { + return window.localStorage.getItem(GETTING_STARTED_OPT_OUT_FLAG) || false; +} + +export function optOutOfGettingStarted() { + window.localStorage.setItem(GETTING_STARTED_OPT_OUT_FLAG, true); + uiChrome.setVisible(true); +} \ No newline at end of file diff --git a/src/ui/public/getting_started/registry.js b/src/ui/public/getting_started/registry.js new file mode 100644 index 00000000000000..f7cb2ce174749a --- /dev/null +++ b/src/ui/public/getting_started/registry.js @@ -0,0 +1,18 @@ +import { uiRegistry } from 'ui/registry/_registry'; + +export const GettingStartedRegistryProvider = uiRegistry({ + name: 'gettingStartedTopMessages', + group: [ 'type' ] +}); + +/** + * Usage: + * + * import { GettingStartedRegistryProvider } from 'ui/getting_started/registry'; + * import { GETTING_STARTED_REGISTRY_TYPES } from 'ui/getting_started/constants'; + * + * GettingStartedRegistryProvider.register(($injector, Private, someOtherService, ...) => ({ + * type: GETTING_STARTED_REGISTRY_TYPES.TOP_MESSAGE, + * template: 'plain text | html markup | markup with directives' + * })); + */ diff --git a/src/ui/public/images/icon-dashboard.svg b/src/ui/public/images/icon-dashboard.svg new file mode 100644 index 00000000000000..d48ff0aa753ddc --- /dev/null +++ b/src/ui/public/images/icon-dashboard.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/ui/public/images/icon-shield.svg b/src/ui/public/images/icon-shield.svg new file mode 100644 index 00000000000000..98a9fa0bdd82cc --- /dev/null +++ b/src/ui/public/images/icon-shield.svg @@ -0,0 +1,14 @@ + + + + icon-security-bb-edited + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/ui/public/images/logo-beats-small.svg b/src/ui/public/images/logo-beats-small.svg new file mode 100644 index 00000000000000..b7666b0238dfb5 --- /dev/null +++ b/src/ui/public/images/logo-beats-small.svg @@ -0,0 +1,23 @@ + + + + +logo-menu + + + + + + + + diff --git a/src/ui/public/images/logo-kibana-small.svg b/src/ui/public/images/logo-kibana-small.svg new file mode 100644 index 00000000000000..094ff605c0fc55 --- /dev/null +++ b/src/ui/public/images/logo-kibana-small.svg @@ -0,0 +1,20 @@ + + + + +logo-menu + + + + + + + + diff --git a/src/ui/public/images/logo-logstash-small.svg b/src/ui/public/images/logo-logstash-small.svg new file mode 100644 index 00000000000000..5a4f62ad021956 --- /dev/null +++ b/src/ui/public/images/logo-logstash-small.svg @@ -0,0 +1,20 @@ + + + + +logo-menu + + + + + + + + diff --git a/src/ui/public/index_patterns/route_setup/load_default.js b/src/ui/public/index_patterns/route_setup/load_default.js deleted file mode 100644 index 715593144e8459..00000000000000 --- a/src/ui/public/index_patterns/route_setup/load_default.js +++ /dev/null @@ -1,58 +0,0 @@ -import _ from 'lodash'; -import { Notifier } from 'ui/notify/notifier'; -import { NoDefaultIndexPattern } from 'ui/errors'; -import { IndexPatternsGetIdsProvider } from '../_get_ids'; -import uiRoutes from 'ui/routes'; -const notify = new Notifier({ - location: 'Index Patterns' -}); - -module.exports = function (opts) { - opts = opts || {}; - const whenMissingRedirectTo = opts.whenMissingRedirectTo || null; - let defaultRequiredToasts = null; - - uiRoutes - .addSetupWork(function loadDefaultIndexPattern(Private, Promise, $route, config) { - const getIds = Private(IndexPatternsGetIdsProvider); - const route = _.get($route, 'current.$$route'); - - return getIds() - .then(function (patterns) { - let defaultId = config.get('defaultIndex'); - let defined = !!defaultId; - const exists = _.contains(patterns, defaultId); - - if (defined && !exists) { - config.remove('defaultIndex'); - defaultId = defined = false; - } - - if (!defined && route.requireDefaultIndex) { - // If there is only one index pattern, set it as default - if (patterns.length === 1) { - defaultId = patterns[0]; - config.set('defaultIndex', defaultId); - } else { - throw new NoDefaultIndexPattern(); - } - } - }); - }) - .afterWork( - // success - null, - - // failure - function (err, kbnUrl) { - const hasDefault = !(err instanceof NoDefaultIndexPattern); - if (hasDefault || !whenMissingRedirectTo) throw err; // rethrow - - kbnUrl.change(whenMissingRedirectTo); - if (!defaultRequiredToasts) defaultRequiredToasts = []; - else defaultRequiredToasts.push(notify.error(err)); - } - ); - - -}; diff --git a/test/functional/apps/console/_console.js b/test/functional/apps/console/_console.js index 64d7190f57709c..8b8c915de67b09 100644 --- a/test/functional/apps/console/_console.js +++ b/test/functional/apps/console/_console.js @@ -15,11 +15,13 @@ export default function ({ getService, getPageObjects }) { const retry = getService('retry'); const log = getService('log'); const screenshots = getService('screenshots'); - const PageObjects = getPageObjects(['common', 'console']); + const PageObjects = getPageObjects(['common', 'console', 'gettingStarted']); describe('console app', function describeIndexTests() { - before(function () { + before(async function () { log.debug('navigateTo console'); + await PageObjects.common.navigateToUrl('settings', 'kibana/getting_started'); + await PageObjects.gettingStarted.clickOptOutLink(); return PageObjects.common.navigateToApp('console'); }); diff --git a/test/functional/config.js b/test/functional/config.js index 050a8d4d0c3ce8..f8a07dcc017a4a 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -12,6 +12,7 @@ import { SettingsPageProvider, MonitoringPageProvider, PointSeriesPageProvider, + GettingStartedPageProvider } from './page_objects'; import { @@ -52,6 +53,7 @@ export default function () { settings: SettingsPageProvider, monitoring: MonitoringPageProvider, pointSeries: PointSeriesPageProvider, + gettingStarted: GettingStartedPageProvider, }, services: { kibanaServer: KibanaServerProvider, diff --git a/test/functional/page_objects/common_page.js b/test/functional/page_objects/common_page.js index 54632e272ae772..ae2f921c4eb978 100644 --- a/test/functional/page_objects/common_page.js +++ b/test/functional/page_objects/common_page.js @@ -23,6 +23,10 @@ export function CommonPageProvider({ getService, getPageObjects }) { return getUrl.baseUrl(config.get('servers.elasticsearch')); } + /** + * @param {string} appName As defined in the apps objects in test/server_config.js + * @param {string} subUrl The route after the hash (#) + */ navigateToUrl(appName, subUrl) { const appConfig = Object.assign({}, config.get(['apps', appName]), { // Overwrite the default hash with the URL we really want. diff --git a/test/functional/page_objects/getting_started_page.js b/test/functional/page_objects/getting_started_page.js new file mode 100644 index 00000000000000..7505718a33b93d --- /dev/null +++ b/test/functional/page_objects/getting_started_page.js @@ -0,0 +1,14 @@ +export function GettingStartedPageProvider({ getService }) { + + const log = getService('log'); + const testSubjects = getService('testSubjects'); + + class GettingStartedPage { + async clickOptOutLink() { + log.debug('Clicking opt-out link'); + await testSubjects.click('lnkGettingStartedOptOut'); + } + } + + return new GettingStartedPage(); +} \ No newline at end of file diff --git a/test/functional/page_objects/index.js b/test/functional/page_objects/index.js index ea811c354d8fde..c7cdb817c3bcbd 100644 --- a/test/functional/page_objects/index.js +++ b/test/functional/page_objects/index.js @@ -9,3 +9,4 @@ export { VisualizePageProvider } from './visualize_page'; export { SettingsPageProvider } from './settings_page'; export { MonitoringPageProvider } from './monitoring_page'; export { PointSeriesPageProvider } from './point_series_page'; +export { GettingStartedPageProvider } from './getting_started_page';