Fix the Admin UI Tests (#1423)

* Fix the Admin UI Tests

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* concurrency

* Fix heal tests

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* fix Logs and trace

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Fix tests that weren't passing

* concurrency

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

Co-authored-by: Kaan Kabalak <kaan@minio.io>
This commit is contained in:
Daniel Valdivia
2022-01-20 16:50:52 -08:00
committed by GitHub
parent 18c14cc452
commit d9531f9617
36 changed files with 469 additions and 256 deletions

View File

@@ -14,18 +14,23 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [1.17.x]
os: [ubuntu-latest]
go-version: [ 1.17.x ]
os: [ ubuntu-latest ]
steps:
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
id: go
- uses: actions/setup-node@v2
with:
node-version: '17'
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Make assets
run: |
make assets
- name: Build Console on ${{ matrix.os }}
env:
GO111MODULE: on
@@ -35,12 +40,12 @@ jobs:
- name: Start Console, front-end app and initialize users/policies
run: |
(./console server && sleep 180) & (cd portal-ui && yarn && yarn start && sleep 180) & (make initialize-permissions && sleep 180)
(./console server && sleep 180) & (make initialize-permissions && sleep 180)
- name: Run TestCafe Tests
uses: DevExpress/testcafe-action@latest
with:
args: '"chrome:headless" portal-ui/tests/permissions/ --skip-js-errors'
args: '"chrome:headless" portal-ui/tests/permissions/ --skip-js-errors '
- name: Clean up users & policies
run: |

View File

@@ -76,10 +76,15 @@ test-permissions:
@(env bash $(PWD)/portal-ui/tests/scripts/permissions.sh)
@(docker stop minio)
initialize-permissions:
@(docker run -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
test-apply-permissions:
@(env bash $(PWD)/portal-ui/tests/scripts/initialize-env.sh)
test-start-docker-minio:
@(docker run -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
initialize-permissions: test-start-docker-minio test-apply-permissions
@echo "Done initializing permissions test"
cleanup-permissions:
@(env bash $(PWD)/portal-ui/tests/scripts/cleanup-env.sh)
@(docker stop minio)

View File

@@ -170,9 +170,8 @@ export const IAM_PAGES = {
TOOLS_DIAGNOSTICS: "/support/diagnostics",
TOOLS_SPEEDTEST: "/support/speedtest",
CALL_HOME: "/support/call-home",
INSPECT: "/support/inspect",
PROFILE: "/support/profile",
TOOLS_WATCH: "/support/watch",
TOOLS_WATCH: "/support/inspect",
/** License **/
LICENSE: "/license",
@@ -389,7 +388,6 @@ export const IAM_PAGES_PERMISSIONS = {
[IAM_PAGES.TOOLS_SPEEDTEST]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.REGISTER_SUPPORT]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.CALL_HOME]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.INSPECT]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.PROFILE]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.HEALTH]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
};

View File

@@ -1316,7 +1316,10 @@ const ListObjects = ({
<Grid item xs={12}>
<br />
</Grid>
<div {...getRootProps({ style: { ...dndStyles } })}>
<div
id="object-list-wrapper"
{...getRootProps({ style: { ...dndStyles } })}
>
<input {...getInputProps()} />
<Grid item xs={12} className={classes.tableBlock}>
<SecureComponent

View File

@@ -80,7 +80,10 @@ const ConfigurationOptions = ({ classes, match }: IConfigurationOptions) => {
<PageLayout>
<Grid item xs={12}>
<div className={classes.settingsOptionsContainer}>
<div
id="settings-container"
className={classes.settingsOptionsContainer}
>
<ScreenTitle icon={<SettingsIcon />} title={"Configuration:"} />
<VerticalTabs
selectedTab={selConfigTab}

View File

@@ -322,7 +322,7 @@ const Console = ({
},
{
component: Tools,
path: IAM_PAGES.INSPECT,
path: IAM_PAGES.TOOLS_WATCH,
},
{
component: Tools,

View File

@@ -290,7 +290,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
actions={
<Fragment>
<span className={classes.statusLabel}>Group Status:</span>
<span className={classes.statusValue}>
<span id="group-status" className={classes.statusValue}>
{isGroupEnabled ? "Enabled" : "Disabled"}
</span>
<SecureComponent

View File

@@ -334,7 +334,9 @@ const ErrorLogs = ({
<SearchBox placeholder="Highlight Line" onChange={setHighlight} />
</Grid>
<Grid item xs={12}>
<div className={classes.logList}>{renderLines}</div>
<div id="logs-container" className={classes.logList}>
{renderLines}
</div>
</Grid>
</Grid>
</PageLayout>

View File

@@ -30,7 +30,12 @@ import {
import { DocumentationIcon, SettingsIcon } from "../../../icons";
import MenuItem from "./MenuItem";
import { NavLink, useLocation } from "react-router-dom";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
import SecureComponent from "../../../common/SecureComponent/SecureComponent";
const ConsoleMenuList = ({
menuItems,
@@ -106,6 +111,7 @@ const ConsoleMenuList = ({
stateClsName={stateClsName}
page={menuGroup}
key={menuGroup.id}
id={menuGroup.id}
onExpand={setOpenGroup}
expandedValue={openGroup}
pathValue={pathname}
@@ -131,34 +137,39 @@ const ConsoleMenuList = ({
}}
className={`${stateClsName} group-wrapper bottom-list`}
>
<ListItem
key={IAM_PAGES.SETTINGS}
button
to={IAM_PAGES.SETTINGS}
disableRipple
component={NavLink}
className={`$ ${stateClsName} bottom-menu-item`}
sx={{
...menuItemContainerStyles,
...menuItemMiniStyles,
marginBottom: "3px",
}}
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_CONFIG_UPDATE]}
resource={CONSOLE_UI_RESOURCE}
>
<ListItemIcon
<ListItem
key={IAM_PAGES.SETTINGS}
button
to={IAM_PAGES.SETTINGS}
disableRipple
component={NavLink}
className={`$ ${stateClsName} bottom-menu-item`}
sx={{
...menuItemIconStyles,
...menuItemContainerStyles,
...menuItemMiniStyles,
marginBottom: "3px",
}}
>
<SettingsIcon />
</ListItemIcon>
<ListItemText
primary="Settings"
sx={{
...menuItemTextStyles,
}}
className={stateClsName}
/>
</ListItem>
<ListItemIcon
sx={{
...menuItemIconStyles,
}}
>
<SettingsIcon />
</ListItemIcon>
<ListItemText
primary="Settings"
sx={{
...menuItemTextStyles,
}}
className={stateClsName}
/>
</ListItem>
</SecureComponent>
<ListItem
button

View File

@@ -43,36 +43,35 @@ import {
} from "../../../icons";
import {
UsersMenuIcon,
BucketsMenuIcon,
IdentityMenuIcon,
MonitoringMenuIcon,
HealthMenuIcon,
GroupsMenuIcon,
AccountsMenuIcon,
MetricsMenuIcon,
LogsMenuIcon,
AuditLogsMenuIcon,
TraceMenuIcon,
DrivesMenuIcon,
AccessMenuIcon,
SupportMenuIcon,
AccountsMenuIcon,
AuditLogsMenuIcon,
BucketsMenuIcon,
DrivesMenuIcon,
GroupsMenuIcon,
HealthMenuIcon,
IdentityMenuIcon,
LogsMenuIcon,
MetricsMenuIcon,
MonitoringMenuIcon,
PerformanceMenuIcon,
InspectMenuIcon,
ProfileMenuIcon,
SupportMenuIcon,
TraceMenuIcon,
UsersMenuIcon,
} from "../../../icons/SidebarMenus/MenuIcons";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES,
S3_ALL_RESOURCES,
IAM_PAGES_PERMISSIONS,
IAM_SCOPES,
S3_ALL_RESOURCES,
} from "../../../common/SecureComponent/permissions";
import { hasPermission } from "../../../common/SecureComponent/SecureComponent";
import MenuToggle from "./MenuToggle";
import ConsoleMenuList from "./ConsoleMenuList";
import RegisterMenuIcon from "../../../icons/SidebarMenus/RegisterMenuIcon";
import DiagnosticsMenuIcon from "../../../icons/SidebarMenus/DiagnosticsMenuIcon";
import CallHomeMenuIcon from "../../../icons/SidebarMenus/CallHomeMenuIcon";
import InspectMenuIcon from "../../../icons/SidebarMenus/InspectMenuIcon";
const drawerWidth = 245;
@@ -146,7 +145,7 @@ const Menu = ({
const ldapIsEnabled = (features && features.includes("ldap-idp")) || false;
let consoleMenus = [
let consoleMenus: IMenuItem[] = [
{
name: "Buckets",
id: "buckets",
@@ -196,8 +195,6 @@ const Menu = ({
id: "access",
to: IAM_PAGES.POLICIES,
icon: AccessMenuIcon,
forceDisplay: true,
children: [],
},
{
component: NavLink,
@@ -290,27 +287,27 @@ const Menu = ({
icon: PerformanceMenuIcon,
to: IAM_PAGES.TOOLS_SPEEDTEST,
},
{
name: "Call Home",
id: "callhome",
component: NavLink,
icon: CallHomeMenuIcon,
to: IAM_PAGES.CALL_HOME,
},
// {
// name: "Call Home",
// id: "callhome",
// component: NavLink,
// icon: CallHomeMenuIcon,
// to: IAM_PAGES.CALL_HOME,
// },
{
name: "Inspect",
id: "inspsect",
id: "inspect",
component: NavLink,
icon: InspectMenuIcon,
to: IAM_PAGES.INSPECT,
},
{
name: "Profile",
id: "profile",
component: NavLink,
icon: ProfileMenuIcon,
to: IAM_PAGES.PROFILE,
to: IAM_PAGES.TOOLS_WATCH,
},
// {
// name: "Profile",
// id: "profile",
// component: NavLink,
// icon: ProfileMenuIcon,
// to: IAM_PAGES.PROFILE,
// },
],
},
{
@@ -371,8 +368,40 @@ const Menu = ({
},
];
const allowedItems = (operatorMode ? operatorMenus : consoleMenus).filter(
(item: IMenuItem) => {
if (item.children && item.children.length > 0) {
const c = item.children?.filter((childItem: IMenuItem) => {
return (
((childItem.customPermissionFnc
? childItem.customPermissionFnc()
: hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[childItem.to ?? ""]
)) ||
childItem.forceDisplay) &&
!childItem.fsHidden
);
});
return c.length > 0;
}
const res =
((item.customPermissionFnc
? item.customPermissionFnc()
: hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[item.to ?? ""]
)) ||
item.forceDisplay) &&
!item.fsHidden;
return res;
}
);
return (
<Drawer
id="app-menu"
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: sidebarOpen,
@@ -394,7 +423,7 @@ const Menu = ({
/>
<ConsoleMenuList
menuItems={operatorMode ? operatorMenus : consoleMenus}
menuItems={allowedItems}
isOpen={sidebarOpen}
onLogoutClick={logout}
/>

View File

@@ -45,12 +45,14 @@ const MenuItem = ({
onExpand,
expandedValue,
pathValue = "",
id = `${Math.random()}`,
}: {
page: any;
stateClsName?: string;
onExpand?: (id: any) => void;
expandedValue?: any;
pathValue?: string;
id?: string;
}) => {
const childrenMenuList = page?.children?.filter(
(item: any) =>
@@ -88,6 +90,7 @@ const MenuItem = ({
onClick={onClickHandler}
component={page.component}
to={page.to}
id={id}
className={`${activeClsName} ${stateClsName} main-menu-item `}
disableRipple
sx={{
@@ -132,7 +135,13 @@ const MenuItem = ({
</ListItem>
{hasChildren ? (
<Collapse key={page.id} in={isActiveGroup} timeout="auto" unmountOnExit>
<Collapse
key={page.id}
id={`${page.id}-children`}
in={isActiveGroup}
timeout="auto"
unmountOnExit
>
<List
component="div"
disablePadding

View File

@@ -15,17 +15,19 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
export interface IMenuItem {
group: string;
type: string;
component: any;
to: string;
group?: string;
type?: string;
component?: any;
to?: string;
name: string;
id?: string;
icon: any;
onClick?: any;
forceDisplay?: boolean;
extraMargin?: boolean;
fsHidden?: boolean;
customPermissionFnc?: any;
children?: IMenuItem[];
}
export interface IRouteRule {

View File

@@ -19,7 +19,7 @@ const mapState = (state: AppState) => ({
const connector = connect(mapState, { setMenuOpen });
const Users = () => {
const Policies = () => {
return (
<Router history={history}>
<Switch>
@@ -28,7 +28,7 @@ const Users = () => {
exact={true}
component={ListPolicies}
/>
<Route path={`"${IAM_PAGES.POLICIES}/*"`} component={PolicyDetails} />
<Route path={`${IAM_PAGES.POLICIES}/*`} component={PolicyDetails} />
<Route path="/" component={ListPolicies} />
<Route component={NotFoundPage} />
</Switch>
@@ -36,4 +36,4 @@ const Users = () => {
);
};
export default withRouter(connector(Users));
export default withRouter(connector(Policies));

View File

@@ -57,7 +57,7 @@ const Tools = () => {
}}
/>
<Route
path={IAM_PAGES.INSPECT}
path={IAM_PAGES.TOOLS_WATCH}
exact
render={() => {
return (

View File

@@ -43,9 +43,7 @@ import { ErrorResponseHandler } from "../../../common/types";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import PageHeader from "../Common/PageHeader/PageHeader";
import api from "../../../common/api";
import BackLink from "../../../common/BackLink";
import PageLayout from "../Common/Layout/PageLayout";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
const styles = (theme: Theme) =>
createStyles({
@@ -184,8 +182,7 @@ const Watch = ({
return (
<React.Fragment>
<PageHeader label="Watch" />
<BackLink to={IAM_PAGES.TOOLS} label="Return to Support" />
<PageHeader label="Inspect" />
<PageLayout>
<Grid item xs={12}>
<Grid item xs={12} className={classes.actionsTray}>

View File

@@ -1 +1 @@
1642030641
1642704125

View File

@@ -15,15 +15,19 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as elements from "../utils/elements-menu";
import { monitoringElement, supportElement } from "../utils/elements-menu";
fixture("For user with Admin permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.admin);
});
test("All sidebar items exist", async (t) => {
const monitoring = elements.monitoringElement;
const identity = elements.identityElement;
const dashboardExists = elements.dashboardElement.exists;
const bucketsExist = elements.bucketsElement.exists;
const usersExist = elements.usersElement.exists;
@@ -34,13 +38,19 @@ test("All sidebar items exist", async (t) => {
const notificationEndpointsExist =
elements.notificationEndpointsElement.exists;
const tiersExist = elements.tiersElement.exists;
const toolsExist = elements.toolsElement.exists;
const toolsExist = elements.supportElement.exists;
const licenseExists = elements.licenseElement.exists;
await t
.expect(monitoring.exists)
.ok()
.click(monitoring)
.expect(dashboardExists)
.ok()
.expect(bucketsExist)
.ok()
.expect(identity.exists)
.ok()
.click(identity)
.expect(usersExist)
.ok()
.expect(groupsExist)
@@ -55,7 +65,14 @@ test("All sidebar items exist", async (t) => {
.ok()
.expect(tiersExist)
.ok()
.expect(toolsExist)
.expect(supportElement.exists)
.ok()
.click(supportElement)
.expect(elements.registerElement.exists)
.ok()
.expect(elements.diagnosticsElement.exists)
.ok()
.expect(elements.performanceElement.exists)
.ok()
.expect(licenseExists)
.ok();

View File

@@ -16,17 +16,19 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";
import { bucketsElement, logoutItem } from "../utils/elements-menu";
fixture("For user with Bucket Assign Policy permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.bucketAssignPolicy);
});
// Bucket assign policy permissions
test("Buckets sidebar item exists", async (t) => {
const bucketsExist = elements.bucketsElement.exists;
const bucketsExist = bucketsElement.exists;
await t.expect(bucketsExist).ok();
});
@@ -38,7 +40,7 @@ test.before(async (t) => {
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
.useRole(roles.bucketAssignPolicy)
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.addAccessRuleButton)
@@ -50,7 +52,7 @@ test.before(async (t) => {
test("A writeonly policy can be assigned to a bucket", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.addAccessRuleButton)
@@ -62,7 +64,7 @@ test("A writeonly policy can be assigned to a bucket", async (t) => {
test("A readwrite policy can be assigned to a bucket", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.addAccessRuleButton)
@@ -74,12 +76,12 @@ test("A readwrite policy can be assigned to a bucket", async (t) => {
test("Previously assigned policy to a bucket can be deleted", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.deleteIconButtonAlt)
.click(elements.deleteButton)
.click(elements.logoutItem);
.click(logoutItem);
}).after(async (t) => {
// Cleanup created bucket
await functions.cleanUpBucket(t);

View File

@@ -17,15 +17,16 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";
import { bucketsElement, logoutItem } from "../utils/elements-menu";
fixture("For user with Bucket Read permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.bucketRead);
});
test("Buckets sidebar item exists", async (t) => {
const bucketsExist = elements.bucketsElement.exists;
const bucketsExist = bucketsElement.exists;
await t.expect(bucketsExist).ok();
});
@@ -33,7 +34,7 @@ test.before(async (t) => {
// Create a bucket
await functions.setUpBucket(t);
})("Browse button exists", async (t) => {
const browseExists = elements.browseButton.exists;
const browseExists = elements.testBucketBrowseButton.exists;
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
await t.useRole(roles.bucketRead).expect(browseExists).ok();
@@ -47,16 +48,16 @@ test
.before(async (t) => {
await t
.useRole(roles.admin)
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.navigateTo("http://localhost:9090/buckets")
.click(elements.testBucketBrowseButton)
// Upload object to bucket
.setFilesToUpload(elements.uploadInput, "../uploads/test.txt")
.click(elements.logoutItem);
.click(logoutItem);
})("Object list table is enabled", async (t) => {
const bucketsTableExists = elements.table.exists;
await t
.useRole(roles.bucketRead)
.click(elements.browseButton)
.click(elements.testBucketBrowseButton)
.expect(bucketsTableExists)
.ok();
})

View File

@@ -17,15 +17,16 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";
import { bucketsElement } from "../utils/elements-menu";
fixture("For user with Bucket Write permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.bucketWrite);
});
test("Buckets sidebar item exists", async (t) => {
const bucketsExist = elements.bucketsElement.with({ boundTestRun: t }).exists;
const bucketsExist = bucketsElement.with({ boundTestRun: t }).exists;
await t.expect(bucketsExist).ok();
});
@@ -33,19 +34,19 @@ test.before(async (t) => {
// Create a bucket
await functions.setUpBucket(t);
})("Browse button exists", async (t) => {
const browseExists = elements.browseButton.exists;
const browseExists = elements.testBucketBrowseButton.exists;
await t
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
.useRole(roles.bucketWrite)
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.expect(browseExists)
.ok();
});
test("Bucket access is set to W", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.expect(elements.bucketAccessText.innerText)
.eql("Access: W");
});
@@ -53,16 +54,16 @@ test("Bucket access is set to W", async (t) => {
test("Upload button exists", async (t) => {
const uploadExists = elements.uploadButton.exists;
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.navigateTo("http://localhost:9090/buckets")
.click(elements.testBucketBrowseButton)
.expect(uploadExists)
.ok();
});
test("Object can be uploaded to a bucket", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.navigateTo("http://localhost:9090/buckets")
.click(elements.testBucketBrowseButton)
// Upload object to bucket
.setFilesToUpload(elements.uploadInput, "../uploads/test.txt");
});
@@ -70,8 +71,8 @@ test("Object can be uploaded to a bucket", async (t) => {
test("Object list table is disabled", async (t) => {
const disabledBucketsTableExists = elements.bucketsTableDisabled.exists;
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.navigateTo("http://localhost:9090/buckets")
.click(elements.testBucketBrowseButton)
.expect(disabledBucketsTableExists)
.ok();
}).after(async (t) => {

View File

@@ -16,16 +16,22 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { dashboardElement, monitoringElement } from "../utils/elements-menu";
fixture("For user with Dashboard permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.dashboard);
});
test("Dashboard sidebar item exists", async (t) => {
const dashboardExists = elements.dashboardElement.exists;
await t.expect(dashboardExists).ok();
const dashboardExists = dashboardElement.exists;
await t
.expect(monitoringElement.exists)
.ok()
.click(monitoringElement)
.expect(dashboardExists)
.ok();
});
// TODO: Display extended metrics

View File

@@ -16,6 +16,7 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { diagnosticsElement, supportElement } from "../utils/elements-menu";
fixture("For user with Diagnostics permissions")
.page("http://localhost:9090")
@@ -23,31 +24,39 @@ fixture("For user with Diagnostics permissions")
await t.useRole(roles.diagnostics);
});
test("Tools sidebar item exists", async (t) => {
const toolsExist = elements.toolsElement.exists;
await t.expect(toolsExist).ok();
test("Support sidebar item exists", async (t) => {
await t
.expect(supportElement.exists)
.ok()
.click(supportElement)
.expect(supportElement.exists)
.ok();
});
test("Diagnostics link exists in Tools page", async (t) => {
const diagnosticsLinkExists = elements.diagnosticsLink.exists;
await t.click(elements.toolsElement).expect(diagnosticsLinkExists).ok();
await t
.expect(supportElement.exists)
.ok()
.click(supportElement)
.expect(diagnosticsElement.exists)
.ok();
});
test("Diagnostics page can be opened", async (t) => {
await t.navigateTo("http://localhost:9090/tools/diagnostics");
await t.navigateTo("http://localhost:9090/support/diagnostics");
});
test("Start Diagnostic button exists", async (t) => {
const startDiagnosticExists = elements.startDiagnosticButton.exists;
await t
.navigateTo("http://localhost:9090/tools/diagnostics")
.navigateTo("http://localhost:9090/support/diagnostics")
.expect(startDiagnosticExists)
.ok();
});
test("Start Diagnostic button can be clicked", async (t) => {
await t
.navigateTo("http://localhost:9090/tools/diagnostics")
.navigateTo("http://localhost:9090/support/diagnostics")
.click(elements.startDiagnosticButton);
});
@@ -56,14 +65,14 @@ test("Start Diagnostic button can be clicked", async (t) => {
// test("Download button exists after Diagnostic is completed", async (t) => {
// const downloadExists = elements.downloadButton.exists;
// await t
// .navigateTo("http://localhost:9090/tools/diagnostics")
// .navigateTo("http://localhost:9090/support/diagnostics")
// .click(elements.startDiagnosticButton)
// .expect(downloadExists).ok();
// });
// test("Download button is clickable after Diagnostic is completed", async (t) => {
// await t
// .navigateTo("http://localhost:9090/tools/diagnostics")
// .navigateTo("http://localhost:9090/support/diagnostics")
// .click(elements.startDiagnosticButton)
// .click(elements.downloadButton);
// });
@@ -72,7 +81,7 @@ test("Start New Diagnostic button exists after Diagnostic is completed", async (
const startNewDiagnosticButtonExists =
elements.startNewDiagnosticButton.exists;
await t
.navigateTo("http://localhost:9090/tools/diagnostics")
.navigateTo("http://localhost:9090/support/diagnostics")
.click(elements.startDiagnosticButton)
.expect(startNewDiagnosticButtonExists)
.ok();
@@ -80,7 +89,7 @@ test("Start New Diagnostic button exists after Diagnostic is completed", async (
test("Start New Diagnostic button is clickable after Diagnostic is completed", async (t) => {
await t
.navigateTo("http://localhost:9090/tools/diagnostics")
.navigateTo("http://localhost:9090/support/diagnostics")
.click(elements.startDiagnosticButton)
.click(elements.startNewDiagnosticButton);
});

View File

@@ -19,40 +19,45 @@ import * as elements from "../utils/elements";
import * as constants from "../utils/constants";
import * as functions from "../utils/functions";
import { Selector } from "testcafe";
import { groupsElement, identityElement } from "../utils/elements-menu";
const groupsListItem = Selector(".ReactVirtualized__Table__rowColumn").withText(
constants.TEST_GROUP_NAME
);
fixture("For user with Groups permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.groups);
});
test("Groups sidebar item exists", async (t) => {
const groupsExist = elements.groupsElement.exists;
await t.expect(groupsExist).ok();
await t
.expect(identityElement.exists)
.ok()
.click(identityElement)
.expect(groupsElement.exists)
.ok();
});
test("Create Group button exists", async (t) => {
const createGroupButtonExists = elements.createGroupButton.exists;
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.expect(createGroupButtonExists)
.ok();
});
test("Create Group button is clickable", async (t) => {
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.click(elements.createGroupButton);
});
test("Group Name input exists in the Create Group modal", async (t) => {
const groupNameInputExists = elements.groupNameInput.exists;
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.click(elements.createGroupButton)
.expect(groupNameInputExists)
.ok();
@@ -61,7 +66,7 @@ test("Group Name input exists in the Create Group modal", async (t) => {
test("Users table exists in the Create Group modal", async (t) => {
const createGroupUserTableExists = elements.table.exists;
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.click(elements.createGroupButton)
.expect(createGroupUserTableExists)
.ok();
@@ -77,7 +82,7 @@ test.before(async (t) => {
// using the specific role we use in this module
await t
.useRole(roles.groups)
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.click(elements.createGroupButton)
.typeText(elements.groupNameInput, constants.TEST_GROUP_NAME)
.typeText(elements.filterUserInput, constants.TEST_USER_NAME)
@@ -89,14 +94,14 @@ test.before(async (t) => {
test("Groups table exists", async (t) => {
const groupsTableExists = elements.table.exists;
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.expect(groupsTableExists)
.ok();
});
test("Created Group can be disabled and enabled back", async (t) => {
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.click(groupsListItem)
.click(elements.switchInput)
.expect(elements.groupStatusText.innerText)
@@ -108,7 +113,7 @@ test("Created Group can be disabled and enabled back", async (t) => {
test("Created Group can be viewed and deleted", async (t) => {
await t
.navigateTo("http://localhost:5005/groups")
.navigateTo("http://localhost:9090/identity/groups")
.click(groupsListItem)
.click(elements.editMembersButton)
.typeText(elements.filterUserInput, constants.TEST_USER_NAME)

View File

@@ -17,6 +17,11 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";
import {
drivesElement,
monitoringElement,
supportElement,
} from "../utils/elements-menu";
fixture("For user with Heal permissions")
.page("http://localhost:9090")
@@ -24,14 +29,17 @@ fixture("For user with Heal permissions")
await t.useRole(roles.heal);
});
test("Tools sidebar item exists", async (t) => {
const toolsExist = elements.toolsElement.exists;
await t.expect(toolsExist).ok();
test("Monitoring sidebar item exists", async (t) => {
await t.expect(monitoringElement.exists).ok();
});
test("Heal link exists in Tools page", async (t) => {
const healLinkExists = elements.healLink.exists;
await t.click(elements.toolsElement).expect(healLinkExists).ok();
test("Heal menu exists in Monitoring page", async (t) => {
await t
.expect(monitoringElement.exists)
.ok()
.click(monitoringElement)
.expect(drivesElement.exists)
.ok();
});
test("Heal page can be opened", async (t) => {

View File

@@ -18,6 +18,7 @@ import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as constants from "../utils/constants";
import { Selector } from "testcafe";
import { iamPoliciesElement } from "../utils/elements-menu";
const iamPolicyListItem = Selector(
".ReactVirtualized__Table__rowColumn"
@@ -29,34 +30,34 @@ const iamPolicyDelete = iamPolicyListItem
.withAttribute("aria-label", "delete");
fixture("For user with IAM Policies permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.iamPolicies);
});
test("IAM Policies sidebar item exists", async (t) => {
const iamPoliciesExist = elements.iamPoliciesElement.exists;
const iamPoliciesExist = iamPoliciesElement.exists;
await t.expect(iamPoliciesExist).ok();
});
test("Create Policy button exists", async (t) => {
const createPolicyButtonExists = elements.createPolicyButton.exists;
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.expect(createPolicyButtonExists)
.ok();
});
test("Create Policy button is clickable", async (t) => {
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.click(elements.createPolicyButton);
});
test("Policy Name input exists in the Create Policy modal", async (t) => {
const policyNameInputExists = elements.createPolicyName.exists;
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.click(elements.createPolicyButton)
.expect(policyNameInputExists)
.ok();
@@ -65,7 +66,7 @@ test("Policy Name input exists in the Create Policy modal", async (t) => {
test("Policy textfield exists in the Create Policy modal", async (t) => {
const policyTextfieldExists = elements.createPolicyTextfield.exists;
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.click(elements.createPolicyButton)
.expect(policyTextfieldExists)
.ok();
@@ -73,7 +74,7 @@ test("Policy textfield exists in the Create Policy modal", async (t) => {
test("Create Policy modal can be submitted after inputs are entered", async (t) => {
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.click(elements.createPolicyButton)
.typeText(elements.createPolicyName, constants.TEST_IAM_POLICY_NAME)
.typeText(elements.createPolicyTextfield, constants.TEST_IAM_POLICY, {
@@ -83,7 +84,7 @@ test("Create Policy modal can be submitted after inputs are entered", async (t)
}).after(async (t) => {
// Clean up created policy
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.typeText(elements.searchResourceInput, constants.TEST_IAM_POLICY_NAME)
.click(iamPolicyDelete)
.click(elements.deleteButton);
@@ -92,7 +93,7 @@ test("Create Policy modal can be submitted after inputs are entered", async (t)
test("Created Policy can be viewed and deleted", async (t) => {
const iamPolicyListItemExists = iamPolicyListItem.exists;
await t
.navigateTo("http://localhost:5005/policies")
.navigateTo("http://localhost:9090/access/policies")
.click(elements.createPolicyButton)
.typeText(elements.createPolicyName, constants.TEST_IAM_POLICY_NAME)
.typeText(elements.createPolicyTextfield, constants.TEST_IAM_POLICY, {

View File

@@ -16,31 +16,39 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import {
logsElement,
monitoringElement,
supportElement,
} from "../utils/elements-menu";
fixture("For user with Logs permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.logs);
});
test("Tools sidebar item exists", async (t) => {
const toolsExist = elements.toolsElement.exists;
await t.expect(toolsExist).ok();
await t.expect(monitoringElement.exists).ok();
});
test("Logs link exists in Tools page", async (t) => {
const logsLinkExists = elements.logsLink.exists;
await t.click(elements.toolsElement).expect(logsLinkExists).ok();
await t
.expect(monitoringElement.exists)
.ok()
.click(monitoringElement)
.expect(logsElement.exists)
.ok();
});
test("Logs page can be opened", async (t) => {
await t.navigateTo("http://localhost:5005/tools/logs");
await t.navigateTo("http://localhost:9090/tools/logs");
});
test("Log window exists in Logs page", async (t) => {
const logWindowExists = elements.logWindow.exists;
await t
.navigateTo("http://localhost:5005/tools/logs")
.navigateTo("http://localhost:9090/tools/logs")
.expect(logWindowExists)
.ok();
});

View File

@@ -16,29 +16,29 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { notificationEndpointsElement } from "../utils/elements-menu";
fixture("For user with Notification Endpoints permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.notificationEndpoints);
});
test("Notification Endpoints sidebar item exists", async (t) => {
const notificationEndpointsExist =
elements.notificationEndpointsElement.exists;
const notificationEndpointsExist = notificationEndpointsElement.exists;
await t.expect(notificationEndpointsExist).ok();
});
test("Add Notification Target button exists", async (t) => {
const addNotifTargetButtonExists = elements.addNotifTargetButton.exists;
await t
.navigateTo("http://localhost:5005/notification-endpoints")
.navigateTo("http://localhost:9090/lambda/notification-endpoints")
.expect(addNotifTargetButtonExists)
.ok();
});
test("Add Notification Target button is clickable", async (t) => {
await t
.navigateTo("http://localhost:5005/notification-endpoints")
.navigateTo("http://localhost:9090/lambda/notification-endpoints")
.click(elements.addNotifTargetButton);
});

View File

@@ -16,22 +16,23 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { settingsElement } from "../utils/elements-menu";
fixture("For user with Settings permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.settings);
});
test("Settings sidebar item exists", async (t) => {
const settingsExist = elements.settingsElement.exists;
const settingsExist = settingsElement.exists;
await t.expect(settingsExist).ok();
});
test("Settings window exists in Settings page", async (t) => {
const settingsWindowExists = elements.settingsWindow.exists;
await t
.navigateTo("http://localhost:5005/settings")
.navigateTo("http://localhost:9090/settings")
.expect(settingsWindowExists)
.ok();
});
@@ -50,7 +51,7 @@ test("All vertical tab items exist", async (t) => {
elements.settingsLoggerWebhookTab.exists;
const settingsAuditWebhookTabExists = elements.settingsAuditWebhookTab.exists;
await t
.navigateTo("http://localhost:5005/settings")
.navigateTo("http://localhost:9090/settings")
.expect(settingsRegionTabExists)
.ok()
.expect(settingsCacheTabExists)

View File

@@ -16,28 +16,29 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { tiersElement } from "../utils/elements-menu";
fixture("For user with Tiers permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.tiers);
});
test("Tiers sidebar item exists", async (t) => {
const tiersExist = elements.tiersElement.exists;
const tiersExist = tiersElement.exists;
await t.expect(tiersExist).ok();
});
test("Add Tier button exists", async (t) => {
const createTierButtonExists = elements.createTierButton.exists;
await t
.navigateTo("http://localhost:5005/tiers")
.navigateTo("http://localhost:9090/tiers")
.expect(createTierButtonExists)
.ok();
});
test("Add Tier button is clickable", async (t) => {
await t
.navigateTo("http://localhost:5005/tiers")
.navigateTo("http://localhost:9090/tiers")
.click(elements.createTierButton);
});

View File

@@ -16,6 +16,11 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import {
monitoringElement,
supportElement,
traceElement,
} from "../utils/elements-menu";
fixture("For user with Trace permissions")
.page("http://localhost:9090")
@@ -23,14 +28,17 @@ fixture("For user with Trace permissions")
await t.useRole(roles.trace);
});
test("Tools sidebar item exists", async (t) => {
const toolsExist = elements.toolsElement.exists;
await t.expect(toolsExist).ok();
test("Monitoring sidebar item exists", async (t) => {
await t.expect(monitoringElement.exists).ok();
});
test("Trace link exists in Tools page", async (t) => {
const traceLinkExists = elements.traceLink.exists;
await t.click(elements.toolsElement).expect(traceLinkExists).ok();
test("Trace link exists in Monitoring menu", async (t) => {
await t
.expect(monitoringElement.exists)
.ok()
.click(monitoringElement)
.expect(traceElement.exists)
.ok();
});
test("Trace page can be opened", async (t) => {

View File

@@ -18,6 +18,7 @@ import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as constants from "../utils/constants";
import { Selector } from "testcafe";
import { identityElement, usersElement } from "../utils/elements-menu";
const userListItem = Selector(".ReactVirtualized__Table__rowColumn").withText(
constants.TEST_USER_NAME
@@ -29,34 +30,39 @@ const userDeleteIconButton = userListItem
.withAttribute("aria-label", "delete");
fixture("For user with Users permissions")
.page("http://localhost:5005")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.users);
});
test("Users sidebar item exists", async (t) => {
const usersExist = elements.usersElement.exists;
await t.expect(usersExist).ok();
const usersExist = usersElement.exists;
await t
.expect(identityElement.exists)
.ok()
.click(identityElement)
.expect(usersExist)
.ok();
});
test("Create User button exists", async (t) => {
const createUserButtonExists = elements.createUserButton.exists;
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.expect(createUserButtonExists)
.ok();
});
test("Create User button is clickable", async (t) => {
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.click(elements.createUserButton);
});
test("Access Key input exists in the Create User modal", async (t) => {
const accessKeyInputExists = elements.usersAccessKeyInput.exists;
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.click(elements.createUserButton)
.expect(accessKeyInputExists)
.ok();
@@ -65,7 +71,7 @@ test("Access Key input exists in the Create User modal", async (t) => {
test("Secret Key input exists in the Create User modal", async (t) => {
const secretKeyInputExists = elements.usersSecretKeyInput.exists;
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.click(elements.createUserButton)
.expect(secretKeyInputExists)
.ok();
@@ -73,7 +79,7 @@ test("Secret Key input exists in the Create User modal", async (t) => {
test("Create User modal can be submitted after inputs are entered", async (t) => {
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.click(elements.createUserButton)
.typeText(elements.usersAccessKeyInput, constants.TEST_USER_NAME)
.typeText(elements.usersSecretKeyInput, constants.TEST_PASSWORD)
@@ -83,7 +89,7 @@ test("Create User modal can be submitted after inputs are entered", async (t) =>
test("Users table exists", async (t) => {
const usersTableExists = elements.table.exists;
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.expect(usersTableExists)
.ok();
});
@@ -91,7 +97,7 @@ test("Users table exists", async (t) => {
test("Created User can be viewed and deleted", async (t) => {
const userListItemExists = userListItem.exists;
await t
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.typeText(elements.searchResourceInput, constants.TEST_USER_NAME)
.expect(userListItemExists)
.ok()

View File

@@ -17,6 +17,11 @@
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";
import {
inspectElement,
monitoringElement,
supportElement,
} from "../utils/elements-menu";
fixture("For user with Watch permissions")
.page("http://localhost:9090")
@@ -24,18 +29,21 @@ fixture("For user with Watch permissions")
await t.useRole(roles.watch);
});
test("Tools sidebar item exists", async (t) => {
const toolsExist = elements.toolsElement.exists;
await t.expect(toolsExist).ok();
test("Support sidebar item exists", async (t) => {
await t.expect(supportElement.exists).ok();
});
test("Watch link exists in Tools page", async (t) => {
const watchLinkExists = elements.watchLink.exists;
await t.click(elements.toolsElement).expect(watchLinkExists).ok();
test("Watch link exists in Support page", async (t) => {
await t
.expect(supportElement.exists)
.ok()
.click(supportElement)
.expect(inspectElement.exists)
.ok();
});
test("Watch page can be opened", async (t) => {
await t.navigateTo("http://localhost:9090/tools/watch");
await t.navigateTo("http://localhost:9090/support/inspect");
});
test
@@ -47,7 +55,7 @@ test
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
.useRole(roles.watch)
.navigateTo("http://localhost:9090/tools/watch")
.navigateTo("http://localhost:9090/support/inspect")
.click(elements.bucketNameInput)
.click(elements.bucketDropdownOption)
.click(elements.startButton);

View File

@@ -0,0 +1,98 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as constants from "./constants";
import { Selector } from "testcafe";
//----------------------------------------------------
// General sidebar element
//----------------------------------------------------
export const sidebarItem = Selector(".MuiPaper-root").find("ul").child("a");
export const logoutItem = Selector(".MuiPaper-root").find("ul").child("div");
//----------------------------------------------------
// Specific sidebar elements
//----------------------------------------------------
export const monitoringElement = Selector(".MuiPaper-root")
.find("ul")
.child("#tools");
export const monitoringChildren = Selector("#tools-children");
export const dashboardElement = monitoringChildren
.find("a")
.withAttribute("href", "/tools/dashboard");
export const logsElement = monitoringChildren
.find("a")
.withAttribute("href", "/tools/logs");
export const traceElement = monitoringChildren
.find("a")
.withAttribute("href", "/tools/trace");
export const drivesElement = monitoringChildren
.find("a")
.withAttribute("href", "/tools/heal");
export const bucketsElement = sidebarItem.withAttribute("href", "/buckets");
export const identityElement = Selector(".MuiPaper-root")
.find("ul")
.child("#identity");
export const identityChildren = Selector("#identity-children");
export const usersElement = identityChildren
.find("a")
.withAttribute("href", "/identity/users");
export const groupsElement = identityChildren
.find("a")
.withAttribute("href", "/identity/groups");
export const serviceAcctsElement = identityChildren
.find("a")
.withAttribute("href", "/identity/account");
export const iamPoliciesElement = sidebarItem.withAttribute(
"href",
"/access/policies"
);
export const settingsElement = sidebarItem.withAttribute("href", "/settings");
export const notificationEndpointsElement = sidebarItem.withAttribute(
"href",
"/lambda/notification-endpoints"
);
export const tiersElement = sidebarItem.withAttribute("href", "/tiers");
export const supportElement = Selector(".MuiPaper-root")
.find("ul")
.child("#support");
export const supportChildren = Selector("#support-children");
export const registerElement = supportChildren
.find("a")
.withAttribute("href", "/support/register");
export const diagnosticsElement = supportChildren
.find("a")
.withAttribute("href", "/support/diagnostics");
export const performanceElement = supportChildren
.find("a")
.withAttribute("href", "/support/speedtest");
export const callHomeElement = supportChildren
.find("a")
.withAttribute("href", "/support/call-home");
export const inspectElement = supportChildren
.find("a")
.withAttribute("href", "/support/inspect");
export const profileElement = supportChildren
.find("a")
.withAttribute("href", "/support/profile");
export const licenseElement = sidebarItem.withAttribute("href", "/license");

View File

@@ -17,36 +17,6 @@
import * as constants from "./constants";
import { Selector } from "testcafe";
//----------------------------------------------------
// General sidebar element
//----------------------------------------------------
export const sidebarItem = Selector(".MuiPaper-root").find("ul").child("a");
export const logoutItem = Selector(".MuiPaper-root").find("ul").child("div");
//----------------------------------------------------
// Specific sidebar elements
//----------------------------------------------------
export const dashboardElement = sidebarItem.withAttribute("href", "/dashboard");
export const bucketsElement = sidebarItem.withAttribute("href", "/buckets");
export const usersElement = sidebarItem.withAttribute("href", "/users");
export const groupsElement = sidebarItem.withAttribute("href", "/groups");
export const serviceAcctsElement = sidebarItem.withAttribute(
"href",
"/account"
);
export const iamPoliciesElement = sidebarItem.withAttribute(
"href",
"/policies"
);
export const settingsElement = sidebarItem.withAttribute("href", "/settings");
export const notificationEndpointsElement = sidebarItem.withAttribute(
"href",
"/notification-endpoints"
);
export const tiersElement = sidebarItem.withAttribute("href", "/tiers");
export const toolsElement = sidebarItem.withAttribute("href", "/tools");
export const licenseElement = sidebarItem.withAttribute("href", "/license");
//----------------------------------------------------
// Buttons
//----------------------------------------------------
@@ -59,7 +29,7 @@ export const manageButton = Selector("h1")
.parent(4)
.find("button:enabled")
.withText("Manage");
export const browseButton = Selector("h1")
export const testBucketBrowseButton = Selector("h1")
.withText(constants.TEST_BUCKET_NAME)
.parent(4)
.find("button:enabled")
@@ -175,15 +145,15 @@ export const bucketAccessText = Selector("h1")
.parent(1)
.find("p")
.nth(-1);
export const groupStatusText = Selector('span[class*="statusValue-"]');
export const groupStatusText = Selector("#group-status");
//----------------------------------------------------
// Tables, table headers and content
//----------------------------------------------------
export const table = Selector(".ReactVirtualized__Table");
export const bucketsTableDisabled = Selector(
'div[class*="TableWrapper-disabled"]'
);
export const bucketsTableDisabled = Selector("#object-list-wrapper")
.find(".MuiPaper-root")
.withText("This location is empty, please try uploading a new file");
export const createGroupUserTable = Selector(
".MuiDialog-container .ReactVirtualized__Table"
);
@@ -197,9 +167,7 @@ export const bucketAccessRulesTab =
//----------------------------------------------------
// Settings window
//----------------------------------------------------
export const settingsWindow = Selector(
'div[class*="ConfigurationOptions-settingsOptionsContainer"]'
);
export const settingsWindow = Selector("#settings-container");
//----------------------------------------------------
// Settings page vertical tabs
@@ -252,4 +220,4 @@ export const settingsAuditWebhookTab = Selector(".MuiTab-root").withAttribute(
//----------------------------------------------------
// Log window
//----------------------------------------------------
export const logWindow = Selector('div[class*="logList"]');
export const logWindow = Selector("#logs-container");

View File

@@ -18,30 +18,31 @@ import * as roles from "./roles";
import * as elements from "./elements";
import * as constants from "./constants";
import { Selector } from "testcafe";
import { logoutItem } from "./elements-menu";
export const setUpBucket = (t) => {
return t
.useRole(roles.admin)
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.click(elements.createBucketButton)
.typeText(elements.bucketNameInput, constants.TEST_BUCKET_NAME)
.click(elements.createBucketButton)
.click(elements.logoutItem);
.click(logoutItem);
};
export const cleanUpBucket = (t) => {
return (
t
// useRole doesn't work here so we would need to enter the commands manually
.navigateTo("http://localhost:5005/login")
.navigateTo("http://localhost:9090/login")
.typeText("#accessKey", "minioadmin")
.typeText("#secretKey", "minioadmin")
.click(elements.loginSubmitButton)
.navigateTo("http://localhost:5005/buckets")
.navigateTo("http://localhost:9090/buckets")
.click(elements.manageButton)
.click(elements.deleteBucketButton)
.click(elements.deleteButton)
.click(elements.logoutItem)
.click(logoutItem)
);
};
@@ -49,25 +50,25 @@ export const cleanUpBucketAndUploads = (t) => {
return (
t
// useRole doesn't work here so we would need to enter the commands manually
.navigateTo("http://localhost:5005/login")
.navigateTo("http://localhost:9090/login")
.typeText("#accessKey", "minioadmin")
.typeText("#secretKey", "minioadmin")
.click(elements.loginSubmitButton)
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.navigateTo("http://localhost:9090/buckets")
.click(elements.testBucketBrowseButton)
.click(elements.deleteIconButtonAlt)
.click(elements.deleteButton)
.click(elements.configureBucketButton)
.click(elements.deleteBucketButton)
.click(elements.deleteButton)
.click(elements.logoutItem)
.click(logoutItem)
);
};
export const createUser = (t) => {
return t
.useRole(roles.admin)
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.click(elements.createUserButton)
.typeText(elements.usersAccessKeyInput, constants.TEST_USER_NAME)
.typeText(elements.usersSecretKeyInput, constants.TEST_PASSWORD)
@@ -86,7 +87,7 @@ export const cleanUpUser = (t) => {
return t
.useRole(roles.admin)
.navigateTo("http://localhost:5005/users")
.navigateTo("http://localhost:9090/identity/users")
.click(userDeleteIconButton)
.click(elements.deleteButton);
};

View File

@@ -4,7 +4,7 @@ import { Role, Selector } from "testcafe";
const data = readFileSync(__dirname + "/../constants/timestamp.txt", "utf-8");
const unixTimestamp = data.trim();
const loginUrl = "http://localhost:5005/login";
const loginUrl = "http://localhost:9090/login";
// diagnostics/watch/trace need to run in port 9090 (through the server) to work
const loginUrlServer = "http://localhost:9090/login";
const submitButton = Selector("form button");