mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Using forceLogout *almost* everywhere (#52922)
* Changing usages of .logout() to .forceLogout() * Using `.logout` from within the security login page test
This commit is contained in:
parent
8d8da48ac8
commit
c8912199d3
25 changed files with 61 additions and 61 deletions
|
@ -17,7 +17,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
|
|||
describe('Login Page', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('empty_kibana');
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@ -25,7 +25,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('meets a11y requirements', async () => {
|
||||
|
|
|
@ -46,7 +46,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login(
|
||||
'global_advanced_settings_all_user',
|
||||
'global_advanced_settings_all_user-password',
|
||||
|
@ -62,7 +62,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_advanced_settings_all_role'),
|
||||
security.user.delete('global_advanced_settings_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'global_canvas_all_user',
|
||||
|
@ -60,7 +60,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_canvas_all_role'),
|
||||
security.user.delete('global_canvas_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -110,11 +110,11 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
after('logout', async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('shows only the dashboard app link', async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('dashuser', '123456');
|
||||
|
||||
const appLinks = await appsMenu.readLinks();
|
||||
|
@ -194,7 +194,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('is loaded for a user who is assigned a non-dashboard mode role', async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('mixeduser', '123456');
|
||||
|
||||
if (await appsMenu.linkExists('Management')) {
|
||||
|
@ -203,7 +203,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('is not loaded for a user who is assigned a superuser role', async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('mysuperuser', '123456');
|
||||
|
||||
if (!await appsMenu.linkExists('Management')) {
|
||||
|
|
|
@ -33,14 +33,14 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await esArchiver.loadIfNeeded('logstash_functional');
|
||||
|
||||
// ensure we're logged out so we can login as the appropriate users
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('discover/feature_controls/security');
|
||||
|
||||
// logout, so the other tests don't accidentally run as the custom users we're testing below
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
describe('global discover all privileges', () => {
|
||||
|
|
|
@ -46,7 +46,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'global_index_patterns_all_user',
|
||||
|
@ -64,7 +64,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_index_patterns_all_role'),
|
||||
security.user.delete('global_index_patterns_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
// ensure we're logged out so we can login as the appropriate users
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@ -37,7 +37,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await security.role.delete('global_all_role');
|
||||
|
||||
// logout, so the other tests don't accidentally run as the custom users we're testing below
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
describe('machine_learning_user', () => {
|
||||
|
|
|
@ -49,7 +49,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login('global_maps_all_user', 'global_maps_all_user-password', {
|
||||
expectSpaceSelector: false,
|
||||
|
@ -60,7 +60,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_maps_all_role'),
|
||||
security.user.delete('global_maps_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ export const getLifecycleMethods = (getService, getPageObjects) => {
|
|||
},
|
||||
|
||||
async tearDown() {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.user.delete('basic_monitoring_user');
|
||||
return esArchiver.unload(_archive);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
after(async () => {
|
||||
await esArchiver.unload('empty_kibana');
|
||||
await PageObjects.common.navigateToApp('home');
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
describe('space with no features disabled', () => {
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login('global_all_user', 'global_all_user-password', {
|
||||
expectSpaceSelector: false,
|
||||
|
@ -55,7 +55,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_all_role'),
|
||||
security.user.delete('global_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -162,7 +162,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login('global_som_read_user', 'global_som_read_user-password', {
|
||||
expectSpaceSelector: false,
|
||||
|
@ -173,7 +173,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_som_read_role'),
|
||||
security.user.delete('global_som_read_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -281,7 +281,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'global_visualize_all_user',
|
||||
|
@ -296,7 +296,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_visualize_all_role'),
|
||||
security.user.delete('global_visualize_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('user East should only see EAST doc', async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('userEast', 'changeme');
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await retry.try(async () => {
|
||||
|
@ -77,7 +77,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
expect(rowData).to.be('name:ABC Company region:EAST _id:doc1 _type: - _index:dlstest _score:0');
|
||||
});
|
||||
after('logout', async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('user customer1 should see ssn', async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('customer1', 'changeme');
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await retry.tryForTime(10000, async () => {
|
||||
|
@ -102,7 +102,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('user customer2 should not see ssn', async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('customer2', 'changeme');
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await retry.tryForTime(10000, async () => {
|
||||
|
@ -114,7 +114,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
after(async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -79,7 +79,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
expect(user.roles).to.eql(['rbac_read']);
|
||||
expect(user.fullname).to.eql('kibanareadonlyFirst kibanareadonlyLast');
|
||||
expect(user.reserved).to.be(false);
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
|
||||
|
@ -100,11 +100,11 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
await PageObjects.visualize.waitForVisualization();
|
||||
await PageObjects.visualize.saveVisualizationExpectSuccess(vizName1);
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -60,7 +60,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
expect(users.Rashmi.roles).to.eql(['logstash_reader', 'kibana_user']);
|
||||
expect(users.Rashmi.fullname).to.eql('RashmiFirst RashmiLast');
|
||||
expect(users.Rashmi.reserved).to.be(false);
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('Rashmi', 'changeme');
|
||||
});
|
||||
|
||||
|
@ -83,7 +83,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
after(async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
describe('Login Page', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('empty_kibana');
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@ -24,7 +24,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('can login', async () => {
|
||||
|
|
|
@ -30,7 +30,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
expect(users.newuser.fullname).to.eql('newuserFirst newuserLast');
|
||||
expect(users.newuser.email).to.eql('newuser@myEmail.com');
|
||||
expect(users.newuser.reserved).to.be(false);
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('login as new user and verify email', async function () {
|
||||
|
@ -41,7 +41,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
it('click changepassword link, change the password and re-login', async function () {
|
||||
await PageObjects.accountSetting.verifyAccountSettings('newuser@myEmail.com', 'newuser');
|
||||
await PageObjects.accountSetting.changePassword('changeme', 'mechange');
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
after(async function () {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export default function enterSpaceFunctonalTests({
|
|||
after(async () => await esArchiver.unload('spaces/enter_space'));
|
||||
|
||||
afterEach(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('allows user to navigate to different spaces, respecting the configured default route', async () => {
|
||||
|
|
|
@ -39,7 +39,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login('global_all_user', 'global_all_user-password', {
|
||||
expectSpaceSelector: false,
|
||||
|
@ -50,7 +50,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('global_all_role'),
|
||||
security.user.delete('global_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -111,7 +111,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'default_space_all_user',
|
||||
|
@ -126,7 +126,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await Promise.all([
|
||||
security.role.delete('default_space_all_role'),
|
||||
security.user.delete('default_space_all_user'),
|
||||
PageObjects.security.logout(),
|
||||
PageObjects.security.forceLogout(),
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function spaceSelectorFunctonalTests({
|
|||
after(async () => await esArchiver.unload('spaces/selector'));
|
||||
|
||||
afterEach(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('allows user to navigate to different spaces', async () => {
|
||||
|
@ -87,7 +87,7 @@ export default function spaceSelectorFunctonalTests({
|
|||
hash: sampleDataHash,
|
||||
});
|
||||
await PageObjects.home.removeSampleDataSet('logs');
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await esArchiver.unload('spaces/selector');
|
||||
});
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ export default function statusPageFunctonalTests({
|
|||
after(async () => await esArchiver.unload('empty_kibana'));
|
||||
|
||||
it('allows user to navigate without authentication', async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.statusPage.navigateToPage();
|
||||
await PageObjects.statusPage.expectStatusPage();
|
||||
});
|
||||
|
|
|
@ -41,7 +41,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'global_timelion_all_user',
|
||||
|
@ -53,7 +53,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('global_timelion_all_role');
|
||||
await security.user.delete('global_timelion_all_user');
|
||||
});
|
||||
|
@ -107,7 +107,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('global_timelion_read_role');
|
||||
await security.user.delete('global_timelion_read_user');
|
||||
});
|
||||
|
@ -151,7 +151,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'no_timelion_privileges_user',
|
||||
|
@ -163,7 +163,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('no_timelion_privileges_role');
|
||||
await security.user.delete('no_timelion_privileges_user');
|
||||
});
|
||||
|
|
|
@ -56,7 +56,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
full_name: 'test user',
|
||||
});
|
||||
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
|
||||
await PageObjects.security.login(
|
||||
'global_visualize_all_user',
|
||||
|
@ -68,7 +68,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('global_visualize_all_role');
|
||||
await security.user.delete('global_visualize_all_user');
|
||||
});
|
||||
|
@ -184,7 +184,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('global_visualize_read_role');
|
||||
await security.user.delete('global_visualize_read_user');
|
||||
});
|
||||
|
@ -294,7 +294,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await security.role.delete('no_visualize_privileges_role');
|
||||
await security.user.delete('no_visualize_privileges_user');
|
||||
});
|
||||
|
|
|
@ -37,7 +37,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
// ensure we're logged out so we can login as the appropriate users
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('license_manager_user', 'license_manager_user-password');
|
||||
},
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
describe('Login Page', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('empty_kibana');
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.forceLogout();
|
||||
});
|
||||
|
||||
it('renders login page', async () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue