From 6366e5b43d6182a43be0ca20b67d0bb0b4765e80 Mon Sep 17 00:00:00 2001 From: tphvu-axonivy Date: Wed, 2 Oct 2024 10:44:05 +0700 Subject: [PATCH 1/2] IVYPORTAL-17700-Remove-portalTest_VERSION_LE - remove portalTest package - move jmeter to portal-selenium-test - move GeckoFireFoxDriver to portal-selenium-test - update Jenkinsfiles --- AxonIvyPortal/PortalTest/.classpath | 29 - AxonIvyPortal/PortalTest/.gitignore | 3 - AxonIvyPortal/PortalTest/.project | 53 - .../.settings/ch.ivyteam.ivy.designer.prefs | 6 - .../org.eclipse.core.resources.prefs | 2 - .../.settings/org.eclipse.jdt.core.prefs | 10 - .../.settings/org.eclipse.m2e.core.prefs | 4 - .../org.eclipse.wst.common.component | 9 - ...se.wst.common.project.facet.core.prefs.xml | 7 - ....eclipse.wst.common.project.facet.core.xml | 6 - .../.settings/org.eclipse.wst.css.core.prefs | 2 - .../PortalTest/config/custom-fields.yaml | 19 - .../PortalTest/config/databases.yaml | 0 AxonIvyPortal/PortalTest/config/formats.yaml | 1 - AxonIvyPortal/PortalTest/config/overrides.any | 1 - .../PortalTest/config/persistence.xml | 2 - .../PortalTest/config/rest-clients.yaml | 0 AxonIvyPortal/PortalTest/config/roles.xml | 4 - AxonIvyPortal/PortalTest/config/users.xml | 2 - .../PortalTest/config/webservice-clients.yaml | 0 AxonIvyPortal/PortalTest/customized_pom.xml | 126 - .../ivy/project/portal/test/Data.ivyClass | 2 - .../PortalTest/document_screenshot_pom.xml | 190 - AxonIvyPortal/PortalTest/pom.xml | 78 - .../resources/config_designer.properties | 5 - .../config_windows_server.properties | 5 - .../resources/copy-decorate-js-css.bat | 4 - .../resources/css/document-screenshot.css | 61 - .../resources/js/document-screenshot.js | 575 - .../testFile/Dashboard_Dashboard_Export.json | 187 - .../custom-case-details-with-panel.json | 92 - .../custom-case-details-with-url.json | 82 - .../testFile/custom-case-details.json | 89 - .../resources/testFile/custom-user-menu.json | 34 - .../testFile/dashboard-has-newsfeed.json | 36 - .../resources/testFile/express-test.json | 125 - .../testFile/express-wf-request-resource.json | 1 - .../express-wf-with-disabled-user.json | 67 - .../testFile/express-wf-with-ransomware.json | 24217 ---------------- .../resources/testFile/sample-file.txt | 1 - .../testFile/task-details-custom-iframe.json | 25 - .../testFile/task-details-custom-panel.json | 53 - .../task-details-custom-process-iframe.json | 39 - .../testFile/test-ms-word-extension.doc | Bin 9216 -> 0 bytes .../testFile/test-no-files-no-js.pdf | Bin 24232 -> 0 bytes .../testFile/test-no-files-with-js.pdf | Bin 7462 -> 0 bytes .../resources/testFile/test-with-macro.doc | Bin 28160 -> 0 bytes .../resources/testFile/test-with-macro.xls | Bin 32256 -> 0 bytes .../testFile/unsupportedExtension.abc | 1 - .../src/portalTest/utils/CaseTestUtils.java | 9 - .../portalkit/service/HistoryServiceTest.java | 129 - .../portalkit/util/ConfigurationJsonUtil.java | 41 - .../portalkit/util/DateTimeFormatterTest.java | 114 - .../ivy/addon/portalkit/util/DatesTest.java | 159 - .../util/DisplayNameConverterTest.java | 26 - .../portalkit/util/ScreenshotMargin.java | 76 - .../addon/portalkit/util/ScreenshotUtil.java | 258 - .../generic/bean/CaseWidgetBeanTest.java | 61 - .../generic/bean/UserMenuBeanTest.java | 70 - .../guitest/bean/ExpressResponsible.java | 21 - .../portal/guitest/common/BaseTest.java | 319 - .../portal/guitest/common/CaseState.java | 17 - .../guitest/common/DateTimePattern.java | 9 - .../portal/guitest/common/FileHelper.java | 9 - .../guitest/common/NavigationHelper.java | 34 - .../common/PortalGUITestException.java | 19 - .../portal/guitest/common/PropertyLoader.java | 55 - .../common/ScreenshotFailedTestRule.java | 64 - .../portal/guitest/common/ScreenshotTest.java | 17 - .../portal/guitest/common/Sleeper.java | 11 - .../guitest/common/SystemProperties.java | 25 - .../portal/guitest/common/TaskState.java | 27 - .../portal/guitest/common/TestAccount.java | 94 - .../portal/guitest/common/TestRole.java | 7 - .../portal/guitest/common/UrlHelpers.java | 44 - .../portal/guitest/common/Variable.java | 76 - .../portal/guitest/common/WaitHelper.java | 122 - .../portal/guitest/page/AbsencePage.java | 191 - .../page/AdditionalCaseDetailsPage.java | 18 - .../portal/guitest/page/AdhocPage.java | 38 - .../guitest/page/AdminSettingsPage.java | 176 - .../portal/guitest/page/AnnouncementPage.java | 33 - .../portal/guitest/page/CaseDetailsPage.java | 915 - .../portal/guitest/page/CaseWidgetPage.java | 483 - .../guitest/page/ChangePasswordPage.java | 56 - .../portal/guitest/page/ChatPage.java | 148 - .../page/DashboardConfigurationPage.java | 199 - ...ashboardWidgetConfigurationDialogPage.java | 241 - .../guitest/page/DefaultExpresTaskPage.java | 23 - .../page/DocumentTableComponentPage.java | 38 - .../guitest/page/ExampleOverviewPage.java | 33 - .../guitest/page/ExpressApprovalPage.java | 28 - .../guitest/page/ExpressBusinessViewPage.java | 65 - .../portal/guitest/page/ExpressEndPage.java | 14 - .../page/ExpressFormDefinitionPage.java | 262 - .../guitest/page/ExpressManagementPage.java | 104 - .../guitest/page/ExpressProcessPage.java | 176 - .../guitest/page/ExpressReviewPage.java | 29 - .../portal/guitest/page/ExpressTaskPage.java | 34 - .../guitest/page/ForgotPasswordPage.java | 45 - .../page/LeaveRequestOverviewPage.java | 29 - .../guitest/page/LendingDetailPage.java | 56 - .../guitest/page/LendingOverviewPage.java | 34 - .../portal/guitest/page/LoginPage.java | 63 - .../portal/guitest/page/MainMenuPage.java | 84 - .../portal/guitest/page/NewAbsencePage.java | 90 - .../portal/guitest/page/NewDashboardPage.java | 221 - .../portal/guitest/page/NoteHistoryPage.java | 68 - .../guitest/page/PasswordResetErrorPage.java | 27 - .../guitest/page/PasswordResetPage.java | 61 - .../guitest/page/PasswordValidationPage.java | 67 - .../portal/guitest/page/ProcessChainPage.java | 28 - .../guitest/page/ProcessHistoryPage.java | 34 - .../guitest/page/ProcessInformationPage.java | 32 - .../page/ProcessViewerComponentPage.java | 20 - .../guitest/page/ProcessViewerPage.java | 25 - .../guitest/page/ProcessWidgetPage.java | 504 - .../guitest/page/ProjectVersionPage.java | 28 - .../guitest/page/RoleManagementPage.java | 216 - .../page/RoleSelectionComponentPage.java | 86 - .../portal/guitest/page/SearchResultPage.java | 153 - ...urityMemberNameAndAvatarComponentPage.java | 24 - .../guitest/page/StatisticWidgetPage.java | 291 - .../guitest/page/TaskAnalysisWidgetPage.java | 378 - .../portal/guitest/page/TaskDetailsPage.java | 489 - .../guitest/page/TaskTemplateIFramePage.java | 88 - .../portal/guitest/page/TaskTemplatePage.java | 340 - .../portal/guitest/page/TaskWidgetPage.java | 953 - .../portal/guitest/page/TemplatePage.java | 555 - .../portal/guitest/page/UserProfilePage.java | 150 - .../page/UserSelectionComponentPage.java | 72 - .../page/UserTaskWithMailFormPage.java | 39 - .../WorkingTaskDialogFromUserProfilePage.java | 21 - .../guitest/page/WorkingTaskDialogPage.java | 21 - ...orkingTaskDialogPageOfApplicationMenu.java | 16 - .../portal/guitest/test/AbsenceTest.java | 279 - .../portal/guitest/test/AdhocExpressTest.java | 112 - .../guitest/test/AdminSettingsTest.java | 85 - .../portal/guitest/test/AnnouncementTest.java | 85 - .../guitest/test/BackNavigationTest.java | 173 - .../portal/guitest/test/BusinessCaseTest.java | 72 - .../test/CaseDescriptionChangeTest.java | 98 - .../portal/guitest/test/CaseDetailsTest.java | 453 - .../portal/guitest/test/CaseFilterTest.java | 145 - .../portal/guitest/test/CaseOwnerTest.java | 59 - .../portal/guitest/test/CaseWidgetTest.java | 307 - .../portal/guitest/test/ChatTest.java | 224 - .../test/ChatTestKillBrowsersTest.java | 27 - .../guitest/test/ClientSideTimeoutTest.java | 48 - .../guitest/test/DateTimeDisplayTest.java | 45 - .../portal/guitest/test/DefaultChartTest.java | 78 - .../portal/guitest/test/DisabledUserTest.java | 100 - .../test/DocumentTableComponentTest.java | 30 - ...nceVisibilityTasksForMemberOfRoleTest.java | 117 - .../guitest/test/ExpressManagementTest.java | 237 - .../portal/guitest/test/ExpressTest.java | 144 - .../guitest/test/ForgotPasswordTest.java | 38 - .../guitest/test/FullProcessPageTest.java | 111 - .../portal/guitest/test/GlobalGrowlTest.java | 152 - .../portal/guitest/test/GlobalSearchTest.java | 24 - .../guitest/test/LanguageSettingTest.java | 56 - .../portal/guitest/test/LoginTest.java | 44 - .../portal/guitest/test/MenuTest.java | 69 - .../guitest/test/PageRefreshingTest.java | 41 - .../guitest/test/PasswordChangeTest.java | 52 - .../guitest/test/PasswordResetTest.java | 65 - .../guitest/test/PasswordValidationTest.java | 99 - .../guitest/test/PortalExpressTest.java | 512 - .../guitest/test/PortalPermissionTest.java | 175 - .../portal/guitest/test/ProcessChainTest.java | 36 - .../guitest/test/ProcessHistoryTest.java | 47 - .../guitest/test/ProcessInformationTest.java | 85 - .../guitest/test/ProcessViewerTest.java | 202 - .../guitest/test/ProcessWidgetTest.java | 90 - .../guitest/test/ProjectVersionTest.java | 22 - .../guitest/test/RoleManagementTest.java | 183 - .../test/RoleSelectionComponentTest.java | 48 - .../portal/guitest/test/SearchCaseTest.java | 62 - .../guitest/test/SearchProcessTest.java | 57 - .../portal/guitest/test/SearchTaskTest.java | 37 - .../guitest/test/ShowCaseNoteHistoryTest.java | 81 - .../guitest/test/ShowRelatedTasksTest.java | 115 - .../guitest/test/ShowTaskNoteHistoryTest.java | 47 - .../portal/guitest/test/SideStepTest.java | 72 - .../guitest/test/StatisticWidgetTest.java | 141 - .../test/SystemNoteVisibilityTest.java | 141 - .../test/SystemTaskHistoryVisibilityTest.java | 60 - .../portal/guitest/test/TaskActionTest.java | 203 - .../guitest/test/TaskAnalysisWidgetTest.java | 337 - .../guitest/test/TaskCategoryMenuTest.java | 34 - .../test/TaskDescriptionChangeTest.java | 105 - .../portal/guitest/test/TaskDetailsTest.java | 243 - .../portal/guitest/test/TaskFilterTest.java | 285 - .../guitest/test/TaskPriorityChangeTest.java | 46 - .../guitest/test/TaskTemplateIFrameTest.java | 120 - .../portal/guitest/test/TaskTemplateTest.java | 153 - .../portal/guitest/test/TaskWidgetTest.java | 242 - .../portal/guitest/test/TopbarTest.java | 56 - .../UploadDeleteDocumentVisibilityTest.java | 88 - .../guitest/test/UploadDocumentTest.java | 141 - .../portal/guitest/test/UserHomepageTest.java | 29 - .../test/UserSelectionComponentTest.java | 41 - .../guitest/userexample/test/CaseMapTest.java | 126 - .../userexample/test/ExampleOverviewTest.java | 84 - .../userexample/test/LeaveRequestTest.java | 107 - .../userexamples/page/CaseMapPage.java | 151 - .../userexamples/page/LeaveRequestPage.java | 104 - .../page/UserExamplesEndPage.java | 19 - AxonIvyPortal/PortalTest/zip.xml | 16 - .../portal_walkthrough_testplan.jmx | 0 .../chat-cluster-try-out/test.properties | 0 .../variables.Portal.Dashboard.json | 0 .../jmeter/data/single_admin_user_local.csv | 0 .../jmeter/data/single_admin_user_server.csv | 0 .../jmeter/data/single_normal_user_local.csv | 0 .../jmeter/data/single_normal_user_server.csv | 0 .../jmeter/data/users_local.csv | 0 .../jmeter/data/users_server.csv | 0 .../jmeter/portal_walkthrough_testplan.jmx | 0 .../jmeter/test.properties | 0 .../resources/GeckoFireFoxDriver.exe | Bin build/create-release/Jenkinsfile | 2 +- build/gui-test-cluster/Jenkinsfile | 91 - build/performance-test/Jenkinsfile | 2 +- build/update-pom/Jenkinsfile | 2 +- 225 files changed, 3 insertions(+), 45586 deletions(-) delete mode 100644 AxonIvyPortal/PortalTest/.classpath delete mode 100644 AxonIvyPortal/PortalTest/.gitignore delete mode 100644 AxonIvyPortal/PortalTest/.project delete mode 100644 AxonIvyPortal/PortalTest/.settings/ch.ivyteam.ivy.designer.prefs delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.core.resources.prefs delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.jdt.core.prefs delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.m2e.core.prefs delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.component delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.xml delete mode 100644 AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.css.core.prefs delete mode 100644 AxonIvyPortal/PortalTest/config/custom-fields.yaml delete mode 100644 AxonIvyPortal/PortalTest/config/databases.yaml delete mode 100644 AxonIvyPortal/PortalTest/config/formats.yaml delete mode 100644 AxonIvyPortal/PortalTest/config/overrides.any delete mode 100644 AxonIvyPortal/PortalTest/config/persistence.xml delete mode 100644 AxonIvyPortal/PortalTest/config/rest-clients.yaml delete mode 100644 AxonIvyPortal/PortalTest/config/roles.xml delete mode 100644 AxonIvyPortal/PortalTest/config/users.xml delete mode 100644 AxonIvyPortal/PortalTest/config/webservice-clients.yaml delete mode 100644 AxonIvyPortal/PortalTest/customized_pom.xml delete mode 100644 AxonIvyPortal/PortalTest/dataclasses/ch/ivyteam/ivy/project/portal/test/Data.ivyClass delete mode 100644 AxonIvyPortal/PortalTest/document_screenshot_pom.xml delete mode 100644 AxonIvyPortal/PortalTest/pom.xml delete mode 100644 AxonIvyPortal/PortalTest/resources/config_designer.properties delete mode 100644 AxonIvyPortal/PortalTest/resources/config_windows_server.properties delete mode 100644 AxonIvyPortal/PortalTest/resources/copy-decorate-js-css.bat delete mode 100644 AxonIvyPortal/PortalTest/resources/css/document-screenshot.css delete mode 100644 AxonIvyPortal/PortalTest/resources/js/document-screenshot.js delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/Dashboard_Dashboard_Export.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-panel.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-url.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/custom-case-details.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/custom-user-menu.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/dashboard-has-newsfeed.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/express-test.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/express-wf-request-resource.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-disabled-user.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-ransomware.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/sample-file.txt delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-iframe.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-panel.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-process-iframe.json delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/test-ms-word-extension.doc delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/test-no-files-no-js.pdf delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/test-no-files-with-js.pdf delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/test-with-macro.doc delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/test-with-macro.xls delete mode 100644 AxonIvyPortal/PortalTest/resources/testFile/unsupportedExtension.abc delete mode 100644 AxonIvyPortal/PortalTest/src/portalTest/utils/CaseTestUtils.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/service/HistoryServiceTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ConfigurationJsonUtil.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DateTimeFormatterTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DatesTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DisplayNameConverterTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotMargin.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotUtil.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/CaseWidgetBeanTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/UserMenuBeanTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/bean/ExpressResponsible.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/BaseTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/CaseState.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/DateTimePattern.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/FileHelper.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/NavigationHelper.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PortalGUITestException.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PropertyLoader.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotFailedTestRule.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Sleeper.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/SystemProperties.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TaskState.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestAccount.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestRole.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/UrlHelpers.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Variable.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/common/WaitHelper.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AbsencePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdditionalCaseDetailsPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdhocPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdminSettingsPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AnnouncementPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseDetailsPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseWidgetPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChangePasswordPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChatPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardConfigurationPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardWidgetConfigurationDialogPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DefaultExpresTaskPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DocumentTableComponentPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExampleOverviewPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressApprovalPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressBusinessViewPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressEndPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressFormDefinitionPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressManagementPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressProcessPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressReviewPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressTaskPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ForgotPasswordPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LeaveRequestOverviewPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingDetailPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingOverviewPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LoginPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/MainMenuPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewAbsencePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewDashboardPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NoteHistoryPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetErrorPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordValidationPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessChainPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessHistoryPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessInformationPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerComponentPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessWidgetPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProjectVersionPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleManagementPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleSelectionComponentPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SearchResultPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SecurityMemberNameAndAvatarComponentPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/StatisticWidgetPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskAnalysisWidgetPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskDetailsPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplateIFramePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplatePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskWidgetPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TemplatePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserProfilePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserSelectionComponentPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserTaskWithMailFormPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogFromUserProfilePage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPageOfApplicationMenu.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AbsenceTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdhocExpressTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdminSettingsTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AnnouncementTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BackNavigationTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BusinessCaseTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDescriptionChangeTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDetailsTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseFilterTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseOwnerTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseWidgetTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTestKillBrowsersTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ClientSideTimeoutTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DateTimeDisplayTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DefaultChartTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DisabledUserTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DocumentTableComponentTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/EnhanceVisibilityTasksForMemberOfRoleTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressManagementTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ForgotPasswordTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/FullProcessPageTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalGrowlTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalSearchTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LanguageSettingTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LoginTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/MenuTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PageRefreshingTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordChangeTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordResetTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordValidationTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalExpressTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalPermissionTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessChainTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessHistoryTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessInformationTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessViewerTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessWidgetTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProjectVersionTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleManagementTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleSelectionComponentTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchCaseTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchProcessTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchTaskTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowCaseNoteHistoryTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowRelatedTasksTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowTaskNoteHistoryTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SideStepTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/StatisticWidgetTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemNoteVisibilityTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemTaskHistoryVisibilityTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskActionTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskAnalysisWidgetTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskCategoryMenuTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDescriptionChangeTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDetailsTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskFilterTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskPriorityChangeTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateIFrameTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskWidgetTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TopbarTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDeleteDocumentVisibilityTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDocumentTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserHomepageTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserSelectionComponentTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/CaseMapTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/ExampleOverviewTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/LeaveRequestTest.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/CaseMapPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/LeaveRequestPage.java delete mode 100644 AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/UserExamplesEndPage.java delete mode 100644 AxonIvyPortal/PortalTest/zip.xml rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/chat-cluster-try-out/portal_walkthrough_testplan.jmx (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/chat-cluster-try-out/test.properties (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/configuration/variables.Portal.Dashboard.json (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/data/single_admin_user_local.csv (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/data/single_admin_user_server.csv (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/data/single_normal_user_local.csv (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/data/single_normal_user_server.csv (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/data/users_local.csv (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/data/users_server.csv (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/portal_walkthrough_testplan.jmx (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/jmeter/test.properties (100%) rename AxonIvyPortal/{PortalTest => portal-selenium-test}/resources/GeckoFireFoxDriver.exe (100%) delete mode 100644 build/gui-test-cluster/Jenkinsfile diff --git a/AxonIvyPortal/PortalTest/.classpath b/AxonIvyPortal/PortalTest/.classpath deleted file mode 100644 index bd53fcbc826..00000000000 --- a/AxonIvyPortal/PortalTest/.classpath +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/.gitignore b/AxonIvyPortal/PortalTest/.gitignore deleted file mode 100644 index 9d915018228..00000000000 --- a/AxonIvyPortal/PortalTest/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/classes/ -/src_dataClasses/ -/target/ \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/.project b/AxonIvyPortal/PortalTest/.project deleted file mode 100644 index a1e5eb6181b..00000000000 --- a/AxonIvyPortal/PortalTest/.project +++ /dev/null @@ -1,53 +0,0 @@ - - - portalTest - - - - - - ch.ivyteam.ivy.designer.dataClasses.ui.ivyDataClassBuilder - - - - - ch.ivyteam.ivy.designer.process.ui.ivyWebServiceProcessClassBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.wst.common.project.facet.core.builder - - - - - ch.ivyteam.ivy.dialog.form.build.ivyDialogFormBuilder - - - - - ch.ivyteam.ivy.designer.ide.ivyModelValidationBuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - ch.ivyteam.ivy.project.IvyProjectNature - org.eclipse.wst.common.modulecore.ModuleCoreNature - org.eclipse.jem.workbench.JavaEMFNature - org.eclipse.jdt.core.javanature - org.eclipse.jem.beaninfo.BeanInfoNature - org.eclipse.wst.common.project.facet.core.nature - - \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/.settings/ch.ivyteam.ivy.designer.prefs b/AxonIvyPortal/PortalTest/.settings/ch.ivyteam.ivy.designer.prefs deleted file mode 100644 index 6308355c142..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/ch.ivyteam.ivy.designer.prefs +++ /dev/null @@ -1,6 +0,0 @@ -ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:DEFAULT_DATA_CLASS=ch.ivyteam.ivy.project.portal.test.Data -ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:DEFAULT_NAMESPACE=ch.ivyteam.ivy.project.portal.test -ch.ivyteam.ivy.project.preferences\:PORTAL_VERSION=10 -ch.ivyteam.ivy.project.preferences\:PRIMEFACES_VERSION=13 -ch.ivyteam.ivy.project.preferences\:PROJECT_VERSION=114006 -eclipse.preferences.version=1 diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.core.resources.prefs b/AxonIvyPortal/PortalTest/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c0203a..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.jdt.core.prefs b/AxonIvyPortal/PortalTest/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 96641ff8bcf..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,10 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 -org.eclipse.jdt.core.compiler.compliance=21 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=21 diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.m2e.core.prefs b/AxonIvyPortal/PortalTest/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index 14b697b7bbb..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.component b/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.component deleted file mode 100644 index 5de0870df7a..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.component +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml deleted file mode 100644 index 0d46547f2b0..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.xml b/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index f9d4879d36f..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.css.core.prefs b/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.css.core.prefs deleted file mode 100644 index 96b96cde35c..00000000000 --- a/AxonIvyPortal/PortalTest/.settings/org.eclipse.wst.css.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -css-profile/=org.eclipse.wst.css.core.cssprofile.css3 -eclipse.preferences.version=1 diff --git a/AxonIvyPortal/PortalTest/config/custom-fields.yaml b/AxonIvyPortal/PortalTest/config/custom-fields.yaml deleted file mode 100644 index 4cfac596740..00000000000 --- a/AxonIvyPortal/PortalTest/config/custom-fields.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# == Custom Fields Information == -# -# You can define here your project custom fields. -# -CustomFields: - Tasks: - # MyTaskCustomField: - # Label: My task custom field - # Description: This new task custom field can be used to ... - # Type: STRING - Cases: - # MyCaseCustomField: - # Label: My case custom field - # Description: This new case custom field can be used to ... - # Type: STRING - Starts: -# MyStartCustomField: -# Label: My start custom field -# Description: This new start custom field can be used to ... diff --git a/AxonIvyPortal/PortalTest/config/databases.yaml b/AxonIvyPortal/PortalTest/config/databases.yaml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/AxonIvyPortal/PortalTest/config/formats.yaml b/AxonIvyPortal/PortalTest/config/formats.yaml deleted file mode 100644 index b33e6cc3dec..00000000000 --- a/AxonIvyPortal/PortalTest/config/formats.yaml +++ /dev/null @@ -1 +0,0 @@ -Formats: diff --git a/AxonIvyPortal/PortalTest/config/overrides.any b/AxonIvyPortal/PortalTest/config/overrides.any deleted file mode 100644 index f59ec20aabf..00000000000 --- a/AxonIvyPortal/PortalTest/config/overrides.any +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/config/persistence.xml b/AxonIvyPortal/PortalTest/config/persistence.xml deleted file mode 100644 index d6b96d79e6a..00000000000 --- a/AxonIvyPortal/PortalTest/config/persistence.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/AxonIvyPortal/PortalTest/config/rest-clients.yaml b/AxonIvyPortal/PortalTest/config/rest-clients.yaml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/AxonIvyPortal/PortalTest/config/roles.xml b/AxonIvyPortal/PortalTest/config/roles.xml deleted file mode 100644 index 59892fed669..00000000000 --- a/AxonIvyPortal/PortalTest/config/roles.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Everybody - diff --git a/AxonIvyPortal/PortalTest/config/users.xml b/AxonIvyPortal/PortalTest/config/users.xml deleted file mode 100644 index 51a690666d4..00000000000 --- a/AxonIvyPortal/PortalTest/config/users.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/AxonIvyPortal/PortalTest/config/webservice-clients.yaml b/AxonIvyPortal/PortalTest/config/webservice-clients.yaml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/AxonIvyPortal/PortalTest/customized_pom.xml b/AxonIvyPortal/PortalTest/customized_pom.xml deleted file mode 100644 index e33e72e543c..00000000000 --- a/AxonIvyPortal/PortalTest/customized_pom.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - 4.0.0 - com.axonivy.portal - portalTest - 9.1.0.0-SNAPSHOT - iar - - 2.0.2 - 12.0.0-SNAPSHOT - 12.0.0 - - - - com.axonivy.portal - portal - 9.1.0.0-SNAPSHOT - iar - - - - junit - junit - 4.13 - test - - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito2 - ${powermock.version} - test - - - - com.jayway.awaitility - awaitility - 1.7.0 - - - vn.wawa - base_gui_test - 3.0.0-SNAPSHOT - - - - ${basedir}/src_test/ - - - com.axonivy.ivy.ci - project-build-plugin - ${build.plugin.version} - true - - UTF-8 - false - - - - start.test.engine - process-test-classes - - start-test-engine - - - - stop.test.engine - - stop-test-engine - - post-integration-test - - - portaltesthelper.deploy - - deploy-to-engine - - - ..\PortalKitTestHelper\target\portalKitTestHelper-${project.version}.iar - demo-portal - - process-test-classes - - - internalsupport.deploy - - deploy-to-engine - - - ..\..\Showcase\InternalSupport\target\internalSupport-${project.version}.iar - demo-portal - - process-test-classes - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M4 - - true - - -Dtest.engine.url=${test.engine.url} - -Dtest.engine.app=demo-portal - - - - - selenium.test - test - - test - - - - - - - \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/dataclasses/ch/ivyteam/ivy/project/portal/test/Data.ivyClass b/AxonIvyPortal/PortalTest/dataclasses/ch/ivyteam/ivy/project/portal/test/Data.ivyClass deleted file mode 100644 index b9a68bf3f1b..00000000000 --- a/AxonIvyPortal/PortalTest/dataclasses/ch/ivyteam/ivy/project/portal/test/Data.ivyClass +++ /dev/null @@ -1,2 +0,0 @@ -Data #class -ch.ivyteam.ivy.project.portal.test #namespace diff --git a/AxonIvyPortal/PortalTest/document_screenshot_pom.xml b/AxonIvyPortal/PortalTest/document_screenshot_pom.xml deleted file mode 100644 index 554845799eb..00000000000 --- a/AxonIvyPortal/PortalTest/document_screenshot_pom.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - 4.0.0 - com.axonivy.portal - portal-document-screenshots - 9.1.0.0-SNAPSHOT - pom - - 2.0.2 - 11.1.0 - 11.3.0 - - - - repo.axongroupio.ch - https://repo.axongroupio.ch/artifactory/ext-release-local/ - - - repo.axongroupio.ch - https://repo.axongroupio.ch/artifactory/ext-snapshot-local/ - - - - - com.axonivy.portal - portal - 9.1.0.0-SNAPSHOT - iar - - - - junit - junit - 4.13 - test - - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito2 - ${powermock.version} - test - - - - com.jayway.awaitility - awaitility - 1.7.0 - - - vn.wawa - base_gui_test - 3.0.0-SNAPSHOT - - - - ${basedir}/src_test/ - - - com.axonivy.ivy.ci - project-build-plugin - ${build.plugin.version} - true - - UTF-8 - false - - - - default-installEngine - - installEngine - - initialize - - - default-compileProject - - compileProject - - compile - - - default-test-compile - - test-compile - - test-compile - - - default-ivy-test-properties - - ivy-test-properties - - test - - - start.test.engine - process-test-classes - - start-test-engine - - - - stop.test.engine - - stop-test-engine - - post-integration-test - - - portaltesthelper.deploy - - deploy-to-engine - - - ..\PortalKitTestHelper\target\portalKitTestHelper-${project.version}.iar - demo-portal - - process-test-classes - - - internalsupport.deploy - - deploy-to-engine - - - ..\..\Showcase\InternalSupport\target\internalSupport-${project.version}.iar - demo-portal - - process-test-classes - - - default-pack-iar - - pack-iar - - none - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M4 - - false - - -Dtest.engine.url=${test.engine.url} - -Dtest.engine.app=demo-portal - - - - - screenshot.test - test - - test - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 3.1.1 - - - package - - single - - - false - - zip.xml - - - - - - - - \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/pom.xml b/AxonIvyPortal/PortalTest/pom.xml deleted file mode 100644 index 2c9bbde8e8f..00000000000 --- a/AxonIvyPortal/PortalTest/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - 4.0.0 - com.axonivy.portal - portalTest - 9.1.0.0-SNAPSHOT - iar - - 12.0.0 - 12.0.0-SNAPSHOT - UTF-8 - 2.0.2 - - - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito2 - ${powermock.version} - test - - - vn.wawa - base_gui_test - 3.0.0-SNAPSHOT - - - com.jayway.awaitility - awaitility - 1.7.0 - - - com.axonivy.portal - portal - 9.1.0.0-SNAPSHOT - iar - - - - ${basedir}/src_test/ - - - com.axonivy.ivy.ci - project-build-plugin - ${build.plugin.version} - true - - false - - - - maven-compiler-plugin - 3.3 - - 17 - 17 - - - - maven-jar-plugin - 3.0.2 - - - - test-jar - - - - - - - diff --git a/AxonIvyPortal/PortalTest/resources/config_designer.properties b/AxonIvyPortal/PortalTest/resources/config_designer.properties deleted file mode 100644 index 27d90e6f03f..00000000000 --- a/AxonIvyPortal/PortalTest/resources/config_designer.properties +++ /dev/null @@ -1,5 +0,0 @@ -server.address = localhost -ivy.engine.port = 8081 -application.name = designer -#browser.type values could be IE, FIREFOX, CHROME -browser.type = FIREFOX \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/config_windows_server.properties b/AxonIvyPortal/PortalTest/resources/config_windows_server.properties deleted file mode 100644 index 95fe38be10b..00000000000 --- a/AxonIvyPortal/PortalTest/resources/config_windows_server.properties +++ /dev/null @@ -1,5 +0,0 @@ -server.address = 192.168.73.8 -ivy.engine.port = 8000 -application.name = Portal -#browser.type values could be IE, FIREFOX, CHROME -browser.type = IE diff --git a/AxonIvyPortal/PortalTest/resources/copy-decorate-js-css.bat b/AxonIvyPortal/PortalTest/resources/copy-decorate-js-css.bat deleted file mode 100644 index 90ca0993444..00000000000 --- a/AxonIvyPortal/PortalTest/resources/copy-decorate-js-css.bat +++ /dev/null @@ -1,4 +0,0 @@ -type AxonivyPortal\PortalTest\resources\css\document-screenshot.css >> AxonivyPortal\portal\webContent\resources\css\portal.css -type AxonivyPortal\PortalTest\resources\css\document-screenshot.css >> Showcase\portal-user-examples\webContent\resources\css\portal-user-examples.css -type AxonivyPortal\PortalTest\resources\js\document-screenshot.js >> AxonivyPortal\portal\webContent\resources\js\portal.js -type AxonivyPortal\PortalTest\resources\js\document-screenshot.js >> Showcase\portal-user-examples\webContent\resources\js\portal-user-examples.js \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/css/document-screenshot.css b/AxonIvyPortal/PortalTest/resources/css/document-screenshot.css deleted file mode 100644 index 51a43b2a10f..00000000000 --- a/AxonIvyPortal/PortalTest/resources/css/document-screenshot.css +++ /dev/null @@ -1,61 +0,0 @@ -/*****CSS FOR DECORATE SCREENSHOT******/ -.marker { - position: absolute !important; - z-index: 9999 !important; - display: inherit; - width: 36px; - height: 36px; - color: #212121; - line-height: 36px; - text-align: center; - text-decoration: none; - border-radius: 50%; - background-color: #b5e61a; -} - -.overlay-text { - position: absolute !important; - z-index: 100 !important; - background: transparent !important; -} - -.red-thick-outline { - outline-style: solid !important; - outline-color: red !important; - outline-width: thick !important; -} - -.red-medium-outline { - outline-style: solid !important; - outline-color: red !important; - outline-width: medium !important; -} - -.red-medium-border { - border: medium solid red !important; -} - -.red-outline-thick-offset { - outline-offset: -5px !important; -} - -.red-medium-border, -.red-topbottom-medium-border, -.red-topbottomleft-medium-border, -.red-topbottomright-medium-border { - border: medium solid red; - z-index: 9999; -} - -.red-topbottom-medium-border { - border-left: 0; - border-right: 0; -} - -.red-topbottomleft-medium-border { - border-right: 0; -} - -.red-topbottomright-medium-border { - border-left: 0; -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/js/document-screenshot.js b/AxonIvyPortal/PortalTest/resources/js/document-screenshot.js deleted file mode 100644 index 2e17a7c9937..00000000000 --- a/AxonIvyPortal/PortalTest/resources/js/document-screenshot.js +++ /dev/null @@ -1,575 +0,0 @@ -/***UTILITY FUNCTIONS FOR ANNOTATION AND HIGHLIGHT****/ -function appendStepAnnotation($element, number, top, left) { - var $marker = $("", {"class": "marker"}).text(number); - var markerTop = $element.offset().top; - var markerLeft = $element.offset().left; - if(top !== undefined) { - $marker.css('top', markerTop + top); - } - if(left !== undefined) { - $marker.css('left', markerLeft + left); - } - $('body').append($marker); -} - -function createRedThickOutline($element) { - $element.addClass("red-thick-outline"); -} - -function createRedMediumOutline($element) { - $element.addClass("red-medium-outline"); -} - -function clearRedMediumOutline($element) { - $element.removeClass("red-medium-outline"); -} - -function createRedMediumBorder($element) { - $element.addClass("red-medium-border"); -} - -function createRedThickOutlineWithOffset($element) { - $element.addClass("red-thick-outline"); - $element.addClass("red-outline-thick-offset"); -} - -/***IMPLEMENTATION TO DECORATE PAGES - WHICH ARE CALLED IN SELENIUM****/ -function highlightDashboardWidget() { - createRedMediumOutline($("#task-widget")); - createRedMediumOutline($("#statistic-widget-container")); - createRedMediumOutline($("#process-widget")); -} - -function highlightAndNumberingDashboardSections() { - var processWidget = $("#process-widget"); - createRedMediumOutline(processWidget); - appendStepAnnotation(processWidget, "1", 0 , processWidget.width()/2); - var taskWidget = $("#task-widget"); - createRedMediumOutline(taskWidget); - appendStepAnnotation(taskWidget, "2", 0, taskWidget.width()/2); - var statisticWidget = $("#statistic-widget-container"); - createRedMediumOutline(statisticWidget); - appendStepAnnotation(statisticWidget, "3", 0, statisticWidget.width()/2); -} - -function numberingTaskFilter() { - var taskOrder = jQuery("#task-widget\\:compact-task-widget-sort-menu"); - appendStepAnnotation(taskOrder, 2, -15,100) -} - -function highlightTopBar() { - var topMenu = $("#top-menu"); - var searchIcon = topMenu.find("li.topbar-item.search-item"); - $(searchIcon).addClass("red-topbottomleft-medium-border"); - var themeSwitchIcon = topMenu.find("li.topbar-item.themeswitch-item"); - $(themeSwitchIcon).addClass("red-topbottom-medium-border"); - var chatItem = topMenu.find("li.topbar-item.chat-item"); - $(chatItem).addClass("red-topbottom-medium-border"); - var userNameItem = topMenu.find("li.topbar-item.user-profile.setting-container"); - $(userNameItem).addClass("red-topbottomright-medium-border"); -} - -function highlightChatIcon() { - var topMenu = $("#top-menu"); - var chatItem = topMenu.find("li.topbar-item.chat-item"); - $(chatItem).addClass("red-medium-border"); -} - -function numberingTopBar() { - var userSetting = $("#user-settings-menu"); - appendStepAnnotation(userSetting, "1", -10, userSetting.width() - 10); - var globalSearch = $("#global-search-component\\:global-search-data"); - appendStepAnnotation(globalSearch, "2", -10, globalSearch.width()-30); -} - -function highlightLogo() { - createRedMediumOutline($(".portal-home-logo.portal-home-logo-small")); -} - -function numberingTaskItem() { - var taskPriorityFirstRow = jQuery(".priority-cell:eq(0)"); - appendStepAnnotation(taskPriorityFirstRow, "1", -35, 0); - - var taskNameFirstRow = jQuery(".task-start-info-task-name:eq(0)"); - appendStepAnnotation(taskNameFirstRow, "2", -10, 160); - - var taskIdSecondRow = jQuery(".task-start-info-task-name:eq(1)"); - appendStepAnnotation(taskIdSecondRow, "3", -10, 170); - - var taskDatesThirddRow = jQuery(".task-start-info-content:eq(2)"); - appendStepAnnotation(taskDatesThirddRow, "4", -10, -45); - appendStepAnnotation(taskDatesThirddRow, "5", -10, 120); - - var taskDescriptionFourthRow = jQuery(".task-start-info-task-description:eq(3)"); - appendStepAnnotation(taskDescriptionFourthRow, "6", -10, 175); -} - -function numberingTaskFilterAndSort() { - var taskFilter = $("#task-widget\\:filter-form\\:filter-container"); - appendStepAnnotation(taskFilter, 1, -15, taskFilter.width()/2); - var taskSort = $("#task-widget\\:sort-task-form\\:sort-task-menu"); - appendStepAnnotation(taskSort, 2, -15, taskSort.width()/2); -} - -function highlightProcessNavigation() { - createRedThickOutlineWithOffset($('.layout-menu .PROCESS')); -} - -function highlightAddExternalLink() { - var externalLink = $('#process-widget\\:add-external-link-command'); - appendStepAnnotation(externalLink, "1", -10, externalLink.width()); -} - -function highlightAddExternalDialogItem() { - var dialogTitle = $('#process-widget\\:add-external-link-dialog_title'); - appendStepAnnotation(dialogTitle, "2", 0, dialogTitle.width()); - - var linkName = $("label[for$='add-external-link-form:external-link-name']"); - appendStepAnnotation(linkName, "3", -5, linkName.width()); - - var startLink = $("label[for$='add-external-link-form:external-link']"); - appendStepAnnotation(startLink, "4", -5, startLink.width()); - - var visibility = $("label[for$='add-external-link-form:external-link-type-radio']"); - appendStepAnnotation(visibility, "5", -5, visibility.width()); - - var icon = $("[id$='add-external-link-form:external-link-icon:awesome-icon-selection']"); - appendStepAnnotation(icon, "6", -10, icon.width()); - - var uploadButton = $("[id$='add-external-link-form:external-link-image-upload']"); - appendStepAnnotation(uploadButton, "7", 0, 80); - - var addButton = $("[id$='process-widget:adding-new-external-link-command']"); - appendStepAnnotation(addButton, "8", -25, -5); -} - -function highlightProcessItems() { - var processSearch = $('[id$="process-widget:process-search"]'); - createRedMediumOutline(processSearch); - appendStepAnnotation(processSearch, "1", -5, processSearch.width() - 40); - - var expressLogo = $('.express-workflow .image-process-icon:eq(0)'); - createRedMediumOutline(expressLogo); - appendStepAnnotation(expressLogo, "2", -15, -30); - - var externalLink = $('.js-external-link-process-item .image-process-icon:eq(0)'); - createRedMediumOutline(externalLink); - appendStepAnnotation(externalLink, "3", -15, -30); - - createRedMediumOutline($('[id$="process-widget:process-view-mode:view-mode-selection"]')); - appendStepAnnotation($("[id$='process-widget:process-view-mode:view-mode-selection'] div[class$='ui-state-active']"), "4", -10, -40); -} - -function highlightEditProcessIcon() { - appendStepAnnotation($("[id$='process-widget:edit-process-form:edit-process-icon:awesome-icon-selection']"), "4", -10, 100); -} - -function highlightEditProcessDialog() { - var dialogTitle = $('#process-widget\\:edit-process-dialog_title'); - appendStepAnnotation(dialogTitle, "3", 0, dialogTitle.width()); -} - -function highlightEditProcessLink() { - let editProcessLink = $('[id$=":0:image-processes:0:process-item:image-process-action-component:edit-process"]'); - createRedMediumBorder(editProcessLink); - appendStepAnnotation(editProcessLink, "2", -10, -40); -} - -function highlightProcessMoreMenuButton() { - let processMoreMenuButton = $('[id$=":0:image-processes:0:process-item:image-process-action-component:process-action-button"]'); - createRedMediumBorder(processMoreMenuButton); - appendStepAnnotation(processMoreMenuButton, "1", -10, -40); -} - -function numberingStatisticWidget() { - var chartInfo = $('.chart-info:eq(0)'); - appendStepAnnotation(chartInfo, "1", -10, 25); - var chartCanvas = $('.ui-carousel-items-content'); - appendStepAnnotation(chartCanvas, "2", chartCanvas.width()/4, chartCanvas.height()/2 + 10); - appendStepAnnotation(chartCanvas, "3", 15, chartCanvas.width()*0.75); -} - -function highlightAdminSettings() { - createRedMediumOutline($("#adminui-menu-item")); -} - -function highlightUserMenuConfiguration() { - createRedMediumOutline($("a[id$='menu-configuration-0']")); - createRedMediumOutline($("a[id$='menu-configuration-1']")); -} - -function highlightCaseMenuItem() { - createRedThickOutlineWithOffset($('.layout-menu .CASE')); -} - -function highlightShowMoreNoteLink() { - createRedMediumOutline($('a.js-note-show-more-link')); -} - -function highlightStatisticNavigation() { - createRedThickOutlineWithOffset($('.layout-menu .STATISTICS')); -} - -function highlightTaskAnalysisNavigationLink() { - createRedMediumOutline($("a[id$=':task-analysis-page-navigation-link']")); -} - -function numberingChartPanel() { - var chartName = $('.chart-name:eq(1)'); - appendStepAnnotation(chartName, "1", -30, -25); - var chartInfo = $('.chart-info:eq(1)'); - appendStepAnnotation(chartInfo, "2", -20, 25); - var chartActions = $('.chart-actions-container:eq(0)'); - appendStepAnnotation(chartActions, "3", -20, 0); - var chartCanvas = $('.statistic-chart:eq(1)'); - appendStepAnnotation(chartCanvas, "4", chartCanvas.width()/4, chartCanvas.height()/2 + 10); - appendStepAnnotation(chartCanvas, "5", 15, chartCanvas.width()*0.8); -} - -function highlightCustomCaseList() { - var caseHeader = $("[id$='case-widget:widget-column-header']"); - createRedMediumOutline(caseHeader); - appendStepAnnotation(caseHeader, "1", -15, caseHeader.width()/2); - - var action = $(".case-header-container.case-header-data:eq(1)"); - createRedMediumOutline(action); - appendStepAnnotation(action, "2", -15, caseHeader.width()/2); -} - -function highlightCustomColumnsConfigOnCaseList() { - var customColumnHeader = $(".ui-commandlink.customized-case-header-column:eq(0)"); - createRedMediumOutline(customColumnHeader) - appendStepAnnotation(customColumnHeader, "1", -30, -20); - - var columnsCheckbox = $("[id$=':select-columns-form:columns-checkbox']"); - var customCheckbox = columnsCheckbox.find("td:eq(5)"); - createRedMediumOutline(customCheckbox); - appendStepAnnotation(customCheckbox, "2", -20, customCheckbox.width() - 10); - - var caseHeader = $(".case-info-row.js-case-start-link:eq(6)"); - var customCaseItemCell = caseHeader.find("span.customized-case-header-column:eq(0)"); - createRedMediumOutline(customCaseItemCell); - appendStepAnnotation(customCaseItemCell, "3", -20, - 20); -} - -function highlightCaseCreatorFilter() { - var filterLabel = $("[id$=':creator-filter:filter-open-form:advanced-filter-command']"); - createRedMediumOutline(filterLabel); - appendStepAnnotation(filterLabel, "1", -25, -30); - - var removeFilterCommand = $("[id$=':creator-filter:filter-open-form:advanced-filter-remove-command']"); - createRedMediumOutline(removeFilterCommand); - appendStepAnnotation(removeFilterCommand, "2", -25, removeFilterCommand.width()); - - var updateCommand = $("[id$=':creator-filter:filter-input-form:update-command']"); - createRedMediumOutline(updateCommand); - appendStepAnnotation(updateCommand, "3", -2, -40) -} - -function highlightEditSwitchProcessButton() { - var editSwitchCommand = $("[id$='process-widget:user-process-action-form:editing-switch-command']"); - createRedMediumOutline(editSwitchCommand); - appendStepAnnotation(editSwitchCommand, "1", -45, editSwitchCommand.width()/2); -} - -function highlightEditStepUserProcess(isDeleteProcess) { - var userProcessList = $("[id$='process-widget:edit-process-item-form:order-list-items']"); - var userProcessItem = userProcessList.find("li.ui-orderlist-item.ui-sortable-handle:eq(0)"); - if (isDeleteProcess) { - var processDeleteLink = userProcessItem.find("[id$=':process-delete-link']"); - createRedMediumOutline(processDeleteLink); - appendStepAnnotation(processDeleteLink, "2", -40, processDeleteLink.width()/2); - } else { - appendStepAnnotation(userProcessItem, "2", 4, userProcessItem.width()/2); - } - - var processSaveLink = $("[id$='process-widget:user-process-action-form:save-process-command']"); - createRedMediumOutline(processSaveLink); - appendStepAnnotation(processSaveLink, "3", -40, -20); -} - -function highlightSortUserProcess() { - createRedMediumOutline($("[id$=':user-process-action-form:name-sort-command']")); -} - -function highlightProcessMoreInformationLink() { - var displayingProcessItem = $(".js-process-start-list-item").filter(function() { - if($(this).css('display') != 'none') - return $(this); - }); - - createRedMediumOutline(displayingProcessItem.find(".process-more-info-link")); -} - -// Task -function highlightCustomTaskList() { - var caseHeader = $("[id$='task-widget:task-widget-sub-header']"); - createRedMediumOutline(caseHeader); - appendStepAnnotation(caseHeader, "1", -15, caseHeader.width()/2); - - var action = $(".full-mode.task-start-list-item.js-task-start-list-item:eq(2)"); - createRedMediumOutline(action); - appendStepAnnotation(action, "2", -15, caseHeader.width()/2); -} - -function highlightCustomColumnsConfigOnTaskList() { - var customColumnHeader = $("[id$=':task-custom']")[0]; - createRedMediumOutline($(customColumnHeader)) - appendStepAnnotation($(customColumnHeader), "1", -30, -20); - - var columnsCheckbox = $("[id$='task-columns-configuration:select-columns-form:columns-checkbox']"); - var customCheckbox = columnsCheckbox.find("td:eq(7)"); - createRedMediumOutline(customCheckbox); - appendStepAnnotation(customCheckbox, "2", -20, customCheckbox.width() - 10); - - var taskHeader = $(".task-start-link.js-task-start-link:eq(4)"); - var customTaskItemCell = taskHeader.find(".task-custom-field-cell"); - createRedMediumOutline(customTaskItemCell); - appendStepAnnotation(customTaskItemCell, "3", -20, - 20); -} - - -function highlightTaskStateFilter() { - var filterLabel = $("[id$=':state-filter:filter-open-form:advanced-filter-command']"); - createRedMediumOutline(filterLabel); - appendStepAnnotation(filterLabel, "1", -25, -30); - - var removeFilterCommand = $("[id$=':state-filter:filter-open-form:advanced-filter-remove-command']"); - createRedMediumOutline(removeFilterCommand); - appendStepAnnotation(removeFilterCommand, "2", -25, removeFilterCommand.width()); - - var updateCommand = $("[id$=':state-filter:filter-input-form:update-command']"); - createRedMediumOutline(updateCommand); - appendStepAnnotation(updateCommand, "3", -2, -40) -} - -function highlightJoinGroupChatOption() { - createRedMediumOutline($('#horizontal-task-action-form\\:chat-group').parent()); -} - -function highlightShowMoreTaskHistories() { - createRedMediumOutline($("[id$=':task-notes:show-more-note-link']")); -} - -function highlightSwitchToEditMode() { - createRedMediumOutline($("[id$=':switch-to-edit-mode-button']")); -} - -function highlightSharePageButton() { - createRedMediumOutline($("[id$=':share-page-button']")); -} - -function highlightSwitchToViewMode() { - createRedMediumOutline($("[id$=':switch-to-view-mode-button']")); -} - -function highlightResetToDefault() { - createRedMediumOutline($("[id$=':reset-details-settings-button']")); -} - -function highlightShowWorkflowEvents() { - createRedMediumOutline($("a[id$=':task-workflow-event-command']")); -} - -function highlightCreateExpressWorkflow() { - createRedMediumOutline($("[id$='process-widget:create-express-link']")); -} - -function highlightExpressTaskResponsible(stepNumber) { - var taskResponsible = '.task-responsible:eq(' + stepNumber + ')'; - createRedMediumOutline($(taskResponsible)); -} - -function highlightManagementExpressTab() { - $("a[href$=':adminTabView:express-management-tab']").parent().addClass("red-medium-border"); -} - -function highlightDeployExpress() { - createRedMediumOutline($(".ui-fileupload-upload")); -} - -function highlightExportExpress() { - var expressTable = $("[id$=':express-management-component:express-management-form:express-workflow-summary-table']"); - var checkAll = expressTable.find(".express-selection-column:eq(0)").find(".ui-chkbox-box"); - createRedMediumOutline(checkAll); - appendStepAnnotation(checkAll, 1, -10, checkAll.width() + 10); - - var exportButton = $("[id$=':express-management-component:express-management-form:export-express-btn']"); - appendStepAnnotation(exportButton, 2, -10, exportButton.width() + 15); -} - -function cleanHighlightExportExpress() { - var expressTable = $("[id$=':express-management-component:express-management-form:express-workflow-summary-table']"); - var checkAll = expressTable.find(".express-selection-column:eq(0)").find(".ui-chkbox-box"); - checkAll.removeClass("red-medium-outline"); - $('.marker').remove(); -} - -function scrollToMiddleOfLayoutContent() { - window.scrollTo(0, document.body.scrollHeight/2); -} - -function scrollToMiddleOfLayoutContent2() { - window.scrollTo(0, document.body.scrollHeight/4); -} - -function scrollToBottomOfLayoutContent() { - window.scrollTo(0, document.body.scrollHeight); -} - -function highlightCustomTaskDetail() { - var customTop = $('.custom-task-details-panel-top'); - appendStepAnnotation(customTop, 1, -45, customTop.width()/2); - - var customBottom = $('.custom-task-details-panel-bottom'); - appendStepAnnotation(customBottom, 2, -45, customBottom.width()/2); -} - -function highlightCustomTaskDetailWithNewStyle() { - var customPanel1 = $('.custom-task-panel-1'); - appendStepAnnotation(customPanel1, 1, -10, customPanel1.width()/2); - - var customPanel2 = $('.custom-task-panel-2'); - appendStepAnnotation(customPanel2, 2, -10, customPanel2.width()/2); - - var customPanel3 = $('.custom-task-panel-3'); - appendStepAnnotation(customPanel3, 3, -10, customPanel3.width()/2); - - var customPanel4 = $('.custom-task-panel-4'); - appendStepAnnotation(customPanel4, 4, -10, customPanel4.width()/2); -} - -function highlightCaseDetailComponents() { - var general = $('#case-details-information-panel'); - appendStepAnnotation(general, 1, 0, general.width()/2); - - var document = $('#case-details-document-panel'); - appendStepAnnotation(document, 2, 0, document.width()/2); - - var technicalCase = $('#case-details-technicalCase-panel'); - appendStepAnnotation(technicalCase, 3, 0, technicalCase.width()/2); - - var relatedTask = $('#case-details-relatedTask-panel'); - appendStepAnnotation(relatedTask, 4, 0, relatedTask.width()/2); - - var histories = $('#case-details-history-panel'); - appendStepAnnotation(histories, 5, 0, histories.width()/2); -} - -function highlightTaskDetailComponent() { - var information = $('#task-details-information-panel'); - appendStepAnnotation(information, 1, 0, information.width()/2); - - var document = $('#task-details-document-panel'); - appendStepAnnotation(document, 2, 0, document.width()/2); - - var histories = $('#task-details-history-panel'); - appendStepAnnotation(histories, 3, 0, histories.width()/2); -} - -function highlightUserExampleCard(cardIndex) { - var userCardId = '#panel-' + cardIndex; - createRedThickOutline($(userCardId).parent()); -} - -function highlightTaskActionItem(taskIndex, actionIndex) { - var taskActionPanelId = ':' + taskIndex + ':task-item:task-action:additional-options:task-additional-actions'; - var actionItemId = '.option-item:eq(' + actionIndex + ')'; - var actionItem = $("[id$='" + taskActionPanelId + "']").find(actionItemId); - createRedMediumOutline(actionItem); -} - -function highlightShowAllProcesses() { - createRedThickOutlineWithOffset($('.layout-menu .PROCESS')); -} - -function highlightShowAdditionalLink() { - createRedMediumOutline($("[id$='case-item:case-item-action-form:action-step-component:show-additional-case-details-link']")); -} - -function highlightTaskExportToExcelButton() { - createRedMediumOutline($("[id$=':task-export-to-excel-form']")); -} - -function highlightCaseExportToExcelButton() { - createRedMediumOutline($("a[id$=':case-export-to-excel']")); -} - -function highlightWidgetExportToExcelLinkForTask() { - createRedMediumOutline($("form[id$=':export-to-excel-form-0'] > a")); -} - -function highlightWidgetExportToExcelLinkForCase() { - createRedMediumOutline($("form[id$=':export-to-excel-form-1'] > a")); -} - -function highlightProcessOverviewLink() { - $(".task-detail-section-title").removeClass("u-truncate-text"); - $(".case-history-button-container").removeClass("u-truncate-text"); - var processOverviewLink = $("a[id$=':show-process-overview-link']"); - processOverviewLink.css("outline-width", "thin"); - processOverviewLink.css("outline-offset", "-1px") - createRedMediumOutline(processOverviewLink); -} - -function highlightCustomWidgetInCaseDetails() { - createRedMediumOutline($(".custom-widget-card")); -} - -function addStepToCustomWidgetTopTaskDetails() { - var topWidget = $(".custom-task-details-panel-top"); - appendStepAnnotation(topWidget, 1, -30, topWidget.width()/2) -} - -function addStepTCustomWidgetTopTaskDetails() { - var bottomWidget = $(".custom-task-details-panel-bottom"); - appendStepAnnotation(bottomWidget, 2, -30, bottomWidget.width()/2) -} - -function highlightIFrameWidgetTaskDetails() { - createRedMediumOutline($(".custom-widget-card.task-detail-card")); -} - -function highlightEmailSettings() { - createRedMediumOutline($("div[id$='email-setting-container']")); -} - -function highlightUserName() { - createRedMediumOutline($('#user-settings-menu')); -} - -function clearHighlightUserName() { - clearRedMediumOutline($('#user-settings-menu')); -} - -function highlightServerInfo() { - createRedMediumOutline($("#server-infor")); -} - -function highlightUserExampleNavigation() { - createRedThickOutlineWithOffset($('.layout-menu .CUSTOM')); -} - -function highlightProcessDisplayModePanel() { - createRedMediumOutline($("div[id $='process-display-mode_panel']")); -} - -function highlightDashboardConfiguration() { - createRedMediumOutline($("#dashboard-configuration")); -} - -function highlightAndNumberingTaskTemplate() { - $(".task-template-title-horizontal-container").css("padding-top", "10px"); - - var title = $("#task-template-title"); - title.css("padding-left", "10px"); - - appendStepAnnotation(title, "1", 0 , title.width()/2 + 70); - - var processChain = $(".process-chain-container"); - appendStepAnnotation(processChain, "2", 0, processChain.width()/2 - 150); - - var other = $("#horizontal-task-template-tasks-command"); - createRedMediumOutline(other); - appendStepAnnotation(other, "3", 27, -20); -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/testFile/Dashboard_Dashboard_Export.json b/AxonIvyPortal/PortalTest/resources/testFile/Dashboard_Dashboard_Export.json deleted file mode 100644 index cd4077ff871..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/Dashboard_Dashboard_Export.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "id" : "1", - "version" : "11.1.0", - "templateId" : "default-portal-dashboard-template", - "titles" : [ { - "locale" : "en", - "value" : "Dashboard" - }, { - "locale" : "fr", - "value" : "Tableau de bord" - }, { - "locale" : "de", - "value" : "Dashboard" - }, { - "locale" : "es", - "value" : "Tablero de mandos" - } ], - "icon" : "si-pie-line-graph", - "widgets" : [ { - "type" : "task", - "id" : "task_1", - "names" : [ { - "locale" : "en", - "value" : "Your Tasks" - }, { - "locale" : "de", - "value" : "Ihre Aufgaben" - }, { - "locale" : "fr", - "value" : "Vos tâches" - }, { - "locale" : "es", - "value" : "Sus tareas" - } ], - "layout" : { - "w" : 9, - "h" : 5, - "x" : 0, - "y" : 2 - }, - "rowsPerPage" : 5, - "canWorkOn" : true, - "sortField" : "startTimestamp", - "sortDescending" : true, - "columns" : [ { - "field" : "start" - }, { - "field" : "priority" - }, { - "field" : "id", - "visible" : false - }, { - "field" : "name" - }, { - "field" : "description" - }, { - "field" : "activator" - }, { - "field" : "state", - "filterList" : [ "CREATED", "DONE", "PARKED", "RESUMED", "SUSPENDED" ] - }, { - "field" : "startTimestamp", - "visible" : false - }, { - "field" : "expiryTimestamp" - }, { - "field" : "category", - "visible" : false - }, { - "field" : "actions" - } ] - }, { - "type" : "case", - "id" : "case_1", - "names" : [ { - "locale" : "en", - "value" : "Your Cases" - }, { - "locale" : "de", - "value" : "Ihre Fälle" - }, { - "locale" : "fr", - "value" : "Vos affaires" - }, { - "locale" : "es", - "value" : "Sus casos" - } ], - "layout" : { - "w" : 12, - "h" : 5, - "x" : 0, - "y" : 7 - }, - "rowsPerPage" : 5, - "sortField" : "startTimestamp", - "sortDescending" : true, - "columns" : [ { - "field" : "id" - }, { - "field" : "name" - }, { - "field" : "description", - "visible" : false - }, { - "field" : "state", - "filterList" : [ "OPEN" ] - }, { - "field" : "creator" - }, { - "field" : "startTimestamp" - }, { - "field" : "endTimestamp", - "visible" : false - }, { - "field" : "category", - "visible" : false - }, { - "field" : "actions" - } ] - }, { - "type" : "compact-process", - "id" : "process_1", - "names" : [ { - "locale" : "en", - "value" : "Your Processes" - }, { - "locale" : "de", - "value" : "Ihre Prozesse" - }, { - "locale" : "fr", - "value" : "Vos processus" - }, { - "locale" : "es", - "value" : "Sus procesos" - } ], - "layout" : { - "w" : 3, - "h" : 5, - "x" : 9, - "y" : 2 - } - }, { - "type" : "welcome", - "id" : "welcome_1", - "names" : [ { - "locale" : "en", - "value" : "Your Welcome Widget" - }, { - "locale" : "fr", - "value" : "Your Welcome Widget" - }, { - "locale" : "de", - "value" : "Your Welcome Widget" - }, { - "locale" : "es", - "value" : "Your Welcome Widget" - } ], - "layout" : { - "w" : 12, - "h" : 2, - "x" : 0, - "y" : 0 - }, - "imageLocation" : "welcome_1_en.jpg", - "imageType" : "image/jpeg", - "welcomeTextPosition" : "TOP_LEFT", - "welcomeTextSize" : "HEADING_3", - "welcomeTextColor" : "ffffff", - "welcomeTexts" : [ { - "locale" : "en", - "value" : ", welcome to the Axon Ivy Portal!" - }, { - "locale" : "fr", - "value" : ", bienvenue sur le portail Axon Ivy!" - }, { - "locale" : "de", - "value" : ", willkommen im Axon Ivy Portal!" - }, { - "locale" : "es", - "value" : ", bienvenido al portal Axon Ivy!" - } ], - "welcomeImageFit" : "COVER", - "imageContent" : "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", - "greeting" : true - } ], - "permissions" : [ "Everybody" ] -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-panel.json b/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-panel.json deleted file mode 100644 index 0510f6a4ae2..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-panel.json +++ /dev/null @@ -1,92 +0,0 @@ -[{ - "id": "default-case-detail", - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "document", - "id": "document", - "layout": { - "w": 6, "h": 8, "x": 6, "y": 0 - } - }, { - "type": "technicalCase", - "id": "technicalCase", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 8 - } - }, { - "type": "relatedTask", - "id": "relatedTask", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 14 - } - }, { - "type": "history", - "id": "history", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 20 - } - } - ] - }, { - "id": "done-case-detail", - "filters": { - "states": ["DESTROYED"] - }, - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "document", - "id": "document", - "layout": { - "w": 6, "h": 8, "x": 6, "y": 0 - } - }, { - "type": "history", - "id": "history", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 8 - } - } - ] - }, { - "id": "custom-case-detail", - "filters": { - "categories": ["customWidget"] - }, - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "id": "caseItemDetailCustomMiddle", - "type": "custom", - "layout": { - "x": 6, "y": 0, "w": 6, "h": 8 - }, - "data": { - "type": "caseItemDetailCustomMiddle" - } - }, { - "id": "caseItemDetailCustomBottom", - "type": "custom", - "layout": { - "x": 0, "y": 8, "w": 12, "h": 6 - }, - "data": { - "type": "caseItemDetailCustomBottom" - } - } - ] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-url.json b/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-url.json deleted file mode 100644 index a0583af3ea3..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details-with-url.json +++ /dev/null @@ -1,82 +0,0 @@ -[{ - "id": "default-case-detail", - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "document", - "id": "document", - "layout": { - "w": 6, "h": 8, "x": 6, "y": 0 - } - }, { - "type": "technicalCase", - "id": "technicalCase", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 8 - } - }, { - "type": "relatedTask", - "id": "relatedTask", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 14 - } - }, { - "type": "history", - "id": "history", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 20 - } - } - ] - }, { - "id": "done-case-detail", - "filters": { - "states": ["DESTROYED"] - }, - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "document", - "id": "document", - "layout": { - "w": 6, "h": 8, "x": 6, "y": 0 - } - }, { - "type": "history", - "id": "history", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 8 - } - } - ] - }, { - "id": "custom-case-detail", - "filters": { - "categories": ["customWidget"] - }, - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "custom", - "layout": { - "x": 6, "y": 0, "w": 6, "h": 8 - }, - "data": { - "url": "https://www.axonivy.com/" - } - } - ] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details.json b/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details.json deleted file mode 100644 index 0b32fbc04f0..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/custom-case-details.json +++ /dev/null @@ -1,89 +0,0 @@ -[{ - "id": "default-case-detail", - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "document", - "id": "document", - "layout": { - "w": 6, "h": 8, "x": 6, "y": 0 - } - }, { - "type": "technicalCase", - "id": "technicalCase", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 8 - } - }, { - "type": "relatedTask", - "id": "relatedTask", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 14 - } - }, { - "type": "history", - "id": "history", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 20 - } - } - ] - }, { - "id": "done-case-detail", - "filters": { - "states": ["DESTROYED"] - }, - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "type": "document", - "id": "document", - "layout": { - "w": 6, "h": 8, "x": 6, "y": 0 - } - }, { - "type": "history", - "id": "history", - "layout": { - "w": 12, "h": 6, "x": 0, "y": 8 - } - } - ] - }, { - "id": "custom-case-detail", - "filters": { - "categories": ["customWidget"] - }, - "widgets": [{ - "type": "information", - "id": "information", - "layout": { - "w": 6, "h": 8, "x": 0, "y": 0 - } - }, { - "id": "custom", - "type": "custom", - "layout": { - "x": 6, "y": 0, "w": 6, "h": 8 - }, - "data": { - "processPath": "Start Processes/CaseDetailsCustomWidgetExample/startReview.ivp", - "params": { - "startedCaseId": "case.id", - "startedCaseCategory": "case.category", - "investmentId": "1573111", - "investmentDescription": "case.customFields.investmentDescription" - } - } - } - ] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/custom-user-menu.json b/AxonIvyPortal/PortalTest/resources/testFile/custom-user-menu.json deleted file mode 100644 index 1f9adb09016..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/custom-user-menu.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "id": "axon-ivy", - "title": "Axon Ivy", - "permissions": [ - "#demo" - ], - "url": "https://www.axonivy.com/" - }, - { - "id": "express", - "title": "Portal Express process", - "permissions": [ - "Everybody" - ], - "url": "Portal Express process" - }, - { - "id": "create-invesment", - "title": "Create Investment", - "permissions": [ - "Employee", - "AXONIVY_PORTAL_ADMIN", - "#daniel" - ], - "url": "Start Processes/DashboardCustomWidgetExample/investmentList.ivp", - "params": { - "embedInFrame" : "true", - "user__customer": "demo", - "date__startDate": "11/19/2021", - "string__note": "a short note for user" - } - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/dashboard-has-newsfeed.json b/AxonIvyPortal/PortalTest/resources/testFile/dashboard-has-newsfeed.json deleted file mode 100644 index 24e8dd80888..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/dashboard-has-newsfeed.json +++ /dev/null @@ -1,36 +0,0 @@ -[{ - "id": "1", - "titles": [{ - "locale": "en", - "value": "Dashboard" - }, { - "locale": "fr", - "value": "Dashboard" - }, { - "locale": "de", - "value": "Dashboard" - }, { - "locale": "es", - "value": "Dashboard" - } - ], - "icon": "si-pie-line-graph", - "widgets": [{ - "type": "news", - "id": "news_1", - "names": [{ - "locale": "en", - "value": "Portal News feed" - } - ], - "layout": { - "w": 4, - "h": 6, - "x": 0, - "y": 14 - } - } - ], - "permissions": ["Everybody"] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/express-test.json b/AxonIvyPortal/PortalTest/resources/testFile/express-test.json deleted file mode 100644 index 1d7e62b5b26..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/express-test.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "version": 1, - "expressWorkflow": [{ - "expressProcess": { - "id": "f5da82a8ed4f437d95b477e9746d9a75", - "processName": "Leave request creation", - "processDescription": "Leave request creation description", - "processType": "AHWF", - "processPermissions": ["#admin"], - "processOwner": "#admin", - "isUseDefaultUI": false, - "processFolder": "e172808e-edd2-4457-8169-f6a48c70bc43", - "readyToExecute": true, - "processCoOwners": ["#admin"], - "isAbleToEdit": true - }, - "expressTaskDefinitions": [{ - "id": "7f0cac61d68346babbebe1e703c578cb", - "processID": "f5da82a8ed4f437d95b477e9746d9a75", - "type": "USER_TASK", - "responsibles": ["#admin"], - "subject": "Express Task 1", - "description": "", - "taskPosition": 1, - "untilDays": 1 - } - ], - "expressFormElements": [{ - "id": "b9d14eba257c40b8b3e628d5defa5479", - "processID": "f5da82a8ed4f437d95b477e9746d9a75", - "elementID": "Test label2019-12-27 11:08:16", - "taskPosition": 1, - "label": "Test Label", - "required": false, - "intSetting": 0, - "elementType": "InputFieldText", - "optionStrs": [""], - "elementPosition": "HEADER", - "indexInPanel": 0, - "counter": 0 - } - ] - }, { - "expressProcess": { - "id": "c3939e7508144f94a03dc71c8054570c", - "processName": "Quality Report", - "processDescription": "Quality Report description", - "processType": "AHWF", - "processPermissions": ["#admin"], - "processOwner": "#admin", - "isUseDefaultUI": false, - "processFolder": "e172808e-edd2-4457-8169-f6a48c70bc43", - "readyToExecute": true, - "processCoOwners": ["#admin"], - "isAbleToEdit": true - }, - "expressTaskDefinitions": [{ - "id": "209f65e4e7344d2ca7d46e0cb39f70b6", - "processID": "c3939e7508144f94a03dc71c8054570c", - "type": "USER_TASK", - "responsibles": ["#admin"], - "subject": "Express Task 1", - "description": "", - "taskPosition": 1, - "untilDays": 1 - } - ], - "expressFormElements": [{ - "id": "4a23be65f8bf4dbb97f0d126a146bfb0", - "processID": "c3939e7508144f94a03dc71c8054570c", - "elementID": "Test label2019-12-27 11:08:16", - "taskPosition": 1, - "label": "Test Label", - "required": false, - "intSetting": 0, - "elementType": "InputFieldText", - "optionStrs": [""], - "elementPosition": "HEADER", - "indexInPanel": 0, - "counter": 0 - } - ] - }, { - "expressProcess": { - "id": "c8166c0a53144adc9eaa1df9c2902f04", - "processName": "Express Test 1", - "processDescription": "Express Test 1", - "processType": "AHWF", - "processPermissions": ["#admin"], - "processOwner": "#admin", - "isUseDefaultUI": false, - "processFolder": "e172808e-edd2-4457-8169-f6a48c70bc43", - "readyToExecute": true, - "processCoOwners": ["#admin"], - "isAbleToEdit": true - }, - "expressTaskDefinitions": [{ - "id": "69cd5fe6730842d394e9025b2b58b56d", - "processID": "c8166c0a53144adc9eaa1df9c2902f04", - "type": "USER_TASK", - "responsibles": ["#admin"], - "subject": "Express Task 1", - "description": "", - "taskPosition": 1, - "untilDays": 1 - } - ], - "expressFormElements": [{ - "id": "269bbeb00a7143c18753e3dc87a273b8", - "processID": "c8166c0a53144adc9eaa1df9c2902f04", - "elementID": "Test label2019-12-27 11:08:16", - "taskPosition": 1, - "label": "Test Label", - "required": false, - "intSetting": 0, - "elementType": "InputFieldText", - "optionStrs": [""], - "elementPosition": "HEADER", - "indexInPanel": 0, - "counter": 0 - } - ] - } - ] -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/testFile/express-wf-request-resource.json b/AxonIvyPortal/PortalTest/resources/testFile/express-wf-request-resource.json deleted file mode 100644 index 546ab95a06f..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/express-wf-request-resource.json +++ /dev/null @@ -1 +0,0 @@ -{"version":2,"expressWorkflow":[{"processName":"Request new Resources - Express process","processDescription":"Express process test ","processType":"AHWF","processPermissions":["#demo","#david"],"processOwner":"#admin","isUseDefaultUI":false,"processFolder":"f647d845-6f04-48c8-82df-5db1ec7da1a4","readyToExecute":true,"processCoOwners":["Everybody"],"icon":"si si-startup-launch","isAbleToEdit":true,"taskDefinitions":[{"type":"USER_TASK","responsibles":["#demo","#david"],"subject":"Promote new resource","description":"Request new resource - Task 1","taskPosition":1,"untilDays":1,"formElements":[{"elementID":"Applicant name2020-07-07 09:29:29","label":"Applicant name","required":true,"intSetting":0,"elementType":"InputFieldText","optionStrs":[""],"elementPosition":"HEADER","indexInPanel":0},{"elementID":"Email2020-07-07 09:29:43","label":"Email","required":false,"intSetting":0,"elementType":"InputFieldText","optionStrs":[""],"elementPosition":"LEFTPANEL","indexInPanel":0},{"elementID":"Address2020-07-07 09:29:35","label":"Address","required":true,"intSetting":0,"elementType":"InputFieldText","optionStrs":[""],"elementPosition":"RIGHTPANEL","indexInPanel":0}]},{"type":"USER_TASK_WITH_EMAIL","responsibles":["Everybody"],"subject":"Send email to HR","description":"Send email to HR for review - Task 2","taskPosition":2,"untilDays":1,"formElements":[{"elementID":"Welcome2020-07-07 09:30:25","label":"Welcome","required":true,"intSetting":0,"elementType":"InputFieldText","optionStrs":[""],"elementPosition":"HEADER","indexInPanel":0}]},{"type":"USER_TASK","responsibles":["#admin"],"subject":"HR review","description":"Wait HR review - Task 3","taskPosition":3,"untilDays":2,"formElements":[{"elementID":"Comment2020-07-07 09:31:05","label":"Comment","required":true,"intSetting":0,"elementType":"InputFieldText","optionStrs":[""],"elementPosition":"FOOTER","indexInPanel":0}]},{"type":"APPROVAL","responsibles":["#admin","Everybody"],"subject":"Approval Request","description":"Approval Request","taskPosition":4,"untilDays":1}],"id":"11e6695de8314d8db059e3a3f34c0183","isPublic":true}]} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-disabled-user.json b/AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-disabled-user.json deleted file mode 100644 index 837fcba4636..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-disabled-user.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "version": 1, - "expressWorkflow": [{ - "expressProcess": { - "id": "1aa339cba44148c8a7215b840b0911b4", - "processName": "Test disabled user", - "processDescription": "Test disabled user", - "processType": "AHWF", - "processPermissions": ["#visibility_test_user", "#demo"], - "processOwner": "#admin", - "isUseDefaultUI": false, - "processFolder": "e26cfb17-4fdd-405c-9aed-4dbfdd7eefe1", - "readyToExecute": true, - "processCoOwners": ["#admin", "#visibility_test_user"], - "isAbleToEdit": true - }, - "expressTaskDefinitions": [{ - "id": "3a059f99084d488a99a8992157589d1c", - "processID": "1aa339cba44148c8a7215b840b0911b4", - "type": "USER_TASK", - "responsibles": ["#visibility_test_user", "#demo"], - "subject": "Task 1 - Test disabled user", - "description": "", - "taskPosition": 1, - "untilDays": 1 - }, { - "id": "4491316e17e947be86ce02ed1e91ba9a", - "processID": "1aa339cba44148c8a7215b840b0911b4", - "type": "USER_TASK", - "responsibles": ["#visibility_test_user"], - "subject": "Task 2 - Test disabled user", - "description": "", - "taskPosition": 2, - "untilDays": 1 - } - ], - "expressFormElements": [{ - "id": "b8dba0d41b1a4290b9f125a29fa2f4f5", - "processID": "1aa339cba44148c8a7215b840b0911b4", - "elementID": "Hello2020-06-01 04:45:15", - "taskPosition": 1, - "label": "Hello", - "required": false, - "intSetting": 0, - "elementType": "InputFieldText", - "optionStrs": [""], - "elementPosition": "LEFTPANEL", - "indexInPanel": 0, - "counter": 0 - }, { - "id": "fb18bb0bf7f2400b949f244fea1bbfc0", - "processID": "1aa339cba44148c8a7215b840b0911b4", - "elementID": "Test 22020-06-01 04:45:27", - "taskPosition": 2, - "label": "Test 2", - "required": false, - "intSetting": 0, - "elementType": "InputFieldText", - "optionStrs": [""], - "elementPosition": "HEADER", - "indexInPanel": 0, - "counter": 0 - } - ] - } - ] -} diff --git a/AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-ransomware.json b/AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-ransomware.json deleted file mode 100644 index 080a0f25cba..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/express-wf-with-ransomware.json +++ /dev/null @@ -1,24217 +0,0 @@ -{ - "authors": [ - "https://docs.google.com/spreadsheets/d/1TWS238xacAto-fLKh1n5uTsdijWdCEsGIM0Y0Hvmc5g/pubhtml", - "http://pastebin.com/raw/GHgpWjar", - "MISP Project", - "https://id-ransomware.blogspot.com/2016/07/ransomware-list.html" - ], - "category": "tool", - "description": "Ransomware galaxy based on https://docs.google.com/spreadsheets/d/1TWS238xacAto-fLKh1n5uTsdijWdCEsGIM0Y0Hvmc5g/pubhtml and http://pastebin.com/raw/GHgpWjar", - "name": "Ransomware", - "source": "Various", - "type": "ransomware", - "uuid": "10cf658b-5d32-4c4b-bb32-61760a640372", - "values": [ - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - "RANDOM 3 LETTERS ARE ADDED" - ], - "payment-method": "Bitcoin", - "price": "1(300$)", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-OkiR6pVmYUw/WMFiLGPuJhI/AAAAAAAAEME/wccYzFDIzJYWKXVxaTQeB4vM-4X6h3atgCLcB/s1600/note-nhtnwcuf.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/nhtnwcuf-ransomware.html" - ] - }, - "uuid": "81b4e3ac-aa83-4616-9899-8e19ee3bb78b", - "value": "Nhtnwcuf Ransomware (Fake)" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - "RANDOM 3 LETTERS ARE ADDED" - ], - "payment-method": "Bitcoin", - "price": "250 €", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-pSmSehFx0bI/WL8Rp7RoMHI/AAAAAAAAEKw/eyfsAjikl9sDHlcjdyQeRxZsLto4hxvGwCLcB/s1600/note-1-2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/cryptojacky-ransomware.html", - "https://twitter.com/jiriatvirlab/status/838779371750031360" - ] - }, - "uuid": "a8187609-329a-4de0-bda7-7823314e7db9", - "value": "CryptoJacky Ransomware" - }, - { - "description": "About: This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-yTOgGw5v_vo/WMBUGHN7bnI/AAAAAAAAELY/8DDyxB4pSWgje_-iVbXgy2agNty1X6D6ACLcB/s1600/C6TUfkZWAAEewi_.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/kaenlupuf-ransomware.html" - ] - }, - "uuid": "b97f07c4-136a-488a-9fa0-35ab45fbfe36", - "value": "Kaenlupuf Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-256", - "extensions": [ - "example:.encrypted.contact_here_me@india.com.enjey" - ], - "payment-method": "Bitcoin", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-rkOR4L9jDZc/WMG1uI6vqQI/AAAAAAAAEMk/SAu_FleTLHcagf_maS31xt3D_qnwAx2RQCLcB/s1600/note-enjey_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/enjey-crypter-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-march-10th-2017-spora-cerber-and-technical-writeups/", - "https://www.bleepingcomputer.com/news/security/embittered-enjey-ransomware-developer-launches-ddos-attack-on-id-ransomware/" - ] - }, - "uuid": "e98e6b50-00fd-484e-a5c1-4b2363579447", - "value": "EnjeyCrypter Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "ransomnotes": [ - "DANGEROUS_RANSOM\nHacked.\nPlease contact\nhakermail@someting.com" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/dangerous-ransomware.html" - ] - }, - "uuid": "7dbdb949-a53b-4ebe-bc9a-7f49a7c5fd78", - "value": "Dangerous Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "extensions": [ - ".aes" - ], - "payment-method": "Dollars", - "price": "199", - "ransomnotes": [ - "Vortex Ransomware\nCan not find the files on the hard drive? The contents of the files do not open?This is the result of the work of the program, which encrypts a lot of your data with the help of a strong algorithm AES-256, used by power structures to mask the data transferred in electronic form.The only way to recover your files is to buy a decryption program from us, using a one-time key created for you!When you decide to restore your data, please contact us by e-mail: rsapl@openmailbox.org or poiskiransom@airmail.cc2 files will be decrypted in vain to prove that we can do it, for the others, unfortunately, have to pay!\nPrice for the decryption of all files: $ 199\nAttention! Do not waste your time,time is money, after 4 days the price will increase by 100%!\nIP = ID =" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/vortex-ransomware.html", - "https://twitter.com/struppigel/status/839778905091424260" - ], - "synonyms": [ - "Ŧl๏tєгค гคภร๏๓ฬคгє" - ] - }, - "uuid": "04a5889d-b97d-4653-8a0f-d2df85f93430", - "value": "Vortex Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "extensions": [ - ".fuck_you" - ], - "payment-method": "Bitcoin", - "price": "0,0361312 (50$)", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-i4i0joM4qRk/WMO7sKLu4dI/AAAAAAAAENU/vLR4B1Xg39wduycHe2f0vEYSv_dtJ-gxwCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/gc47-ransomware.html" - ] - }, - "uuid": "2069c483-4701-4a3b-bd51-3850c7aa59d2", - "value": "GC47 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. ", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "extensions": [ - ".enc", - ".ENC" - ], - "payment-method": "Bitcoin", - "price": "10000 Rubles (135€)", - "ransomnotes": [ - "OUR FILES are encrypted (EVEN NOT LOOKING THAT THEY ARE PARTIALLY OPEN). WE HAVE YOUR LOGIN AND PASSWORD FROM THE ENTERTAINMENT, ONE-CLASSICS, ONLINE BANKS AND OTHERS.\nYOU HAVE 6 HOURS TO PAY FOR A PURCHASE FOR THEM, OTHERWISE WE SHOULD PUT INTO OPEN ACCESS!\nINSTRUCTION:\n1) Find 10 000 (10 thousand) rubles, not less. Suitable for the following - (Qiwi, Sberbank, Yandex.Money, Tinkoff Bank, VTB, but better Qiwi (faster)\n2) In the browser, open the site https://x-pay.cc/ - through this site you will transfer money\n3) In the column I DELETE where you will translate (according to item 1) and above enter the amount - 10,000 rubles.\n4) In the RIGHT I select Bitcoin and on top the amount should automatically be transferred tobtc\n5) In the column DATA ENTRY, fill in your requisites from where you will pay and where to transfer (Bitcoin wallet)\nATTENTION-ATTENTION,CORRECTly copy this number to a purse (yes, it's so strange)3FjtFZWjyj46UcfDY4AiUrEv7wLtyzZv5o After inserting, carefully, again check whether it is copied correctly.\n6) Click on GO TO PAY and follow the instructions on the site.\nIn a couple of hours we'll write you on the desktop and return everything to you.\nIf there are difficulties, then write on the mailbox - aoneder@mail.ru" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/rozalocker-ransomware.html", - "https://twitter.com/jiriatvirlab/status/840863070733885440" - ], - "synonyms": [ - "Roza" - ] - }, - "uuid": "f158ea74-c8ba-4e5a-b07f-52bd8fe30888", - "value": "RozaLocker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "extensions": [ - ".enc" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes": [ - "Blocked Your computer has been blocked All your files are encrypted. To access your PC, you need to send to Bitcoin at the address below loading Step 1: Go to xxxxs : //wvw.coinbase.com/ siqnup Step 2: Create an account and follow the instructions Step 3: Go to the \"Buy Bitcoins\" section and then buy Bitcoin Step 4: Go to the \"Send\" section, enter the address above and the amount (0.1 Bitcoin) Step 5: Click on the button below to verify the payment, your files will be decrypted and the virus will disappear 'Check' If you try to bypass the lock, all files will be published on the Internet, as well as your login for all sites." - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/cryptomeister-ransomware.html" - ] - }, - "uuid": "4c76c845-c5eb-472c-93a1-4178f86c319b", - "value": "CryptoMeister Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Poses as Hewlett-Packard 2016", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "extensions": [ - ".GG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/gg-ransomware.html" - ] - }, - "uuid": "f62eb881-c6b5-470c-907d-072485cd5860", - "value": "GG Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "extensions": [ - ".Project34" - ], - "payment-method": "MoneyPak", - "price": "300$", - "ransomnotes": [ - "(TRANSLATED BY THE SITE EDITOR) YOUR FILES HAVE BEEN LOCKED WITH A PASSWORD TO GET THE PASSWORD WRITE TO US AT project34@india.com WE WILL RESPOND TO YOU WITHIN 20 HOURS IN A MESSAGE, SPECIFY YOUR IP ADDRESS. YOU CAN FIND OUT AT 2IP.RU" - ], - "ransomnotes-filenames": [ - "ПАРОЛЬ.txt" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/project34-ransomware.html" - ] - }, - "uuid": "4af0d2bd-46da-44da-b17e-987f86957c1d", - "value": "Project34 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "payment-method": "Bitcoin", - "price": "300$", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-ZbWrN1LR-14/WMhPB7M8LBI/AAAAAAAAERQ/ZGG3RDHd8V0hwK_pf-vYChTn9VRpLBgNQCLcB/s1600/petya-based_ru_3.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/petrwrap-ransomware.html", - "https://www.bleepingcomputer.com/news/security/petrwrap-ransomware-is-a-petya-offspring-used-in-targeted-attacks/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-march-17th-2017-revenge-petrwrap-and-captain-kirk/", - "https://securelist.com/blog/research/77762/petrwrap-the-new-petya-based-ransomware-used-in-targeted-attacks/" - ] - }, - "uuid": "e11da570-e38d-4290-8a2c-8a31ae832ffb", - "value": "PetrWrap Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. RaaS, baed on HiddenTear", - "meta": { - "date": "March 2017", - "encryption": "AES-128", - "extensions": [ - ".grt" - ], - "payment-method": "Bitcoin", - "price": "1.2683", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-OmuOKzLOHnw/WMl74fSSaJI/AAAAAAAAESg/4CsOYOSuUeEhsO4jSi6k10sbb_1NnfYxACLcB/s1600/lock-screen.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-march-17th-2017-revenge-petrwrap-and-captain-kirk/", - "https://id-ransomware.blogspot.co.il/2017/03/karmen-ransomware.html", - "https://twitter.com/malwrhunterteam/status/841747002438361089" - ] - }, - "uuid": "da7de60e-0725-498d-9a35-303ddb5bf60a", - "value": "Karmen Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. CryptoMix / CryptFile2 Variant", - "meta": { - "date": "March 2017", - "encryption": "AES-256 + RSA-1024", - "extensions": [ - ".REVENGE" - ], - "ransomnotes": [ - "===ENGLISH=== All of your files were encrypted using REVENGE Ransomware. The action required to restore the files. Your files are not lost, they can be returned to their normal state by decoding them. The only way to do this is to get the software and your personal decryption key. Using any other software that claims to be able to recover your files will result in corrupted or destroyed files. You can purchase the software and the decryption key by sending us an email with your ID. And we send instructions for payment. After payment, you receive the software to return all files. For proof, we can decrypt one file for free. Attach it to an e-mail." - ], - "ransomnotes-filenames": [ - "# !!!HELP_FILE!!! #.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-KkPVDxjy8tk/WM7LtYHmuAI/AAAAAAAAEUw/kDJghaq-j1AZuqjzqk2Fkxpp4yr9Yeb5wCLcB/s1600/revenge-note-2.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/revenge-ransomware-a-cryptomix-variant-being-distributed-by-rig-exploit-kit/", - "https://id-ransomware.blogspot.co.il/2017/03/revenge-ransomware.html" - ] - }, - "uuid": "987d36d5-6ba8-484d-9e0b-7324cc886b0e", - "value": "Revenge Ransomware" - }, - { - "description": "his is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "150$", - "ransomnotes": [ - "FILES NUMBERED Your local drives, network folders, your external drives are encrypted using 256-bit encryption technology, this means your files are encrypted with a key. They cannot be opened without buying a decryption program and a private key, after the purchase, our program decrypts all your files and they will work like before. If you do not buy the program within 24 hours, then all your files will be permanently deleted. See the \"My Documents\" folder for more information in the file \"Beni Oku.txt\". Contact address: d3crypt0r@lelantos.org BTC address: 13hp68keuvogyjhvlf7xqmeox8dpr8odx5 You have to pay at BTC to the above address $ 150 Bitcoin You can do this by purchasing Bitcoinat www.localbitcoins.co Information: Using a computer recovery does not help. Antivirus scanning does not help to recover files, but can lead to loss." - ], - "ransomnotes-filenames": [ - "Beni Oku.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-ccU4txzjpWg/WMl33c7YD3I/AAAAAAAAESU/moLHgQnVMYstKuHKuNgWKz8VbNv5ECdzACLcB/s1600/lock-note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/turkish-fileencryptor.html", - "https://twitter.com/JakubKroustek/status/842034887397908480" - ], - "synonyms": [ - "Fake CTB-Locker" - ] - }, - "uuid": "a291ac4c-7851-480f-b317-e977a616ac9d", - "value": "Turkish FileEncryptor Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Payments in Monero", - "meta": { - "date": "March 2017", - "encryption": "AES+RSA", - "extensions": [ - ".kirked", - ".Kirked" - ], - "payment-method": "Monero", - "price": "1100 roupies (14€)", - "ransomnotes": [ - "!IMPORTANT ! READ CAREFULLY: Your computer has fallen victim to the Kirk malware and important files have been encrypted - locked up so they don't work. This may have broken some software, including games, office suites etc. Here's a list of some the file extensions that were targetted : *** There are an additional 441 file extensions that are targetted\n. They are mostly to do with games. To get your files back, you need to pay. Now. Payments\nrecieved more than 48 hours after the time of infection will be charged double. Further time penalties are listed below. The time of infection has been logged. Any files with the extensions listed above will now have the extra extension '.kirked\n', these files are encrypted using military grade encryption.In the place you ran this program from, you should find a note (named RANSOM_NOTE.txt) similar to this one.\nYou will also find a file named 'pwd' - this is your encrypted password file. Although it was generated by your computer, you have no way of ever decrypting it. This is due to the security of both the way it was generated and the way it was encrypted. Your files were encrypted using this password. SPOCK TO THE RESCUE!\n\"Logic, motherfucker.\" ~ Spock.\nDecrypting your files is easy. Take a deep breath and follow the steps below.1) Make the proper payment. Payments are made in Monero. This is a crypto-currency, like bitcoin. You can buy Monero, and send it, from the same places you can any othercrypto-currency. If you're still unsure, google' bitcoin exchange'. Sign up at one of these exchange sites and send the payment to the address below. Make note of the payment / transaction ID, or make one up if you have the option. Payment Address (Monero Wallet): 3000375 -199390 0 0 4AqSwfTexbNaHcn8giSJw3KPiWYHGBaCF9bdgPxvHbd5A8Q3Fc7n6FQCReEns8uEg8jUo4BeB79rwf4XSfQPVL1SKdVp2jz Prices: Days :Monero: Offer Expires\n 0-2 : 50 : 03/18/17 15:32:14\n 3-7 : 100 : 03/23/17 15:32:14\n 8-14 : 200 : 03/30/17 15:32:14\n 15-30 : 500 : 04/15/17 15:32:14 Note: In 31 days your password decryption key gets permanently deleted. You then have no way to ever retrieve your files. So pay now \n2) Email us Send your pwd file as an email attachment to one of the email addresses below. Include the payment ID from step 1. Active email addresses: kirk.help@scryptmail.com kirk.payments@scryptmail.com \n3) Decrypt your files. You will recieve your decrypted password file and a program called 'Spock'. Download these both to the same place and run Spock. Spock reads in your decrypted password file and uses it to decrypt all of the affected files on your computer. > IMPORTANT ! The password is unique to this infection. Using an old password or one from another machine will result in corrupted files. Corrupted files cannot be retrieved. Don't fuck around. \n4) Breathe. \nLIVE LONG AND PROSPER" - ], - "ransomnotes-filenames": [ - "RANSOM_NOTE.txt" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-USLFJX6OMD4/WMwmKIsJnEI/AAAAAAAAETQ/S8uzyHF5mWQZjra6EGBidZ6wqgzrNqIMgCLcB/s1600/full-ransom-note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/kirkspock-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-march-17th-2017-revenge-petrwrap-and-captain-kirk/", - "https://www.bleepingcomputer.com/forums/t/642239/kirk-ransomware-help-support-topic-kirk-extension-ransom-notetxt/", - "http://www.networkworld.com/article/3182415/security/star-trek-themed-kirk-ransomware-has-spock-decryptor-demands-ransom-be-paid-in-monero.html", - "http://www.securityweek.com/star-trek-themed-kirk-ransomware-emerges", - "https://www.grahamcluley.com/kirk-ransomware-sports-star-trek-themed-decryptor-little-known-crypto-currency/", - "https://www.virustotal.com/en/file/39a2201a88f10d81b220c973737f0becedab2e73426ab9923880fb0fb990c5cc/analysis/" - ], - "synonyms": [ - "Kirk & Spock Decryptor" - ] - }, - "uuid": "6e442a2e-97db-4a7b-b4a1-9abb4a7472d8", - "value": "Kirk Ransomware & Spock Decryptor" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".ZINO" - ], - "payment-method": "Bitcoin", - "ransomnotes-filenames": [ - "ZINO_NOTE.TXT" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-t1Q-a7sJlag/WMw8MBNIrkI/AAAAAAAAET4/aycY-m5GXVYQjcbZJ8N0kIfUZ3onYt8AgCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/zinocrypt-ransomware.html", - "https://twitter.com/demonslay335?lang=en", - "https://twitter.com/malwrhunterteam/status/842781575410597894" - ] - }, - "uuid": "719c8ba7-598e-4511-a851-34e651e301fa", - "value": "ZinoCrypt Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Uses @enigma0x3's UAC bypass", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".crptxxx" - ], - "ransomnotes-filenames": [ - "HOW_TO_FIX_!.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-itq9nR2EedY/WM2OPtDKCgI/AAAAAAAAEUI/KcC8vtnmlHENz0CSOvxqoYeZL8qdx1IZgCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/crptxxx-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/609690/ultracrypter-cryptxxx-ultradecrypter-ransomware-help-topic-crypt-cryp1/page-84", - "http://www.fixinfectedpc.com/uninstall-crptxxx-ransomware-from-pc", - "https://twitter.com/malwrhunterteam/status/839467168760725508" - ] - }, - "uuid": "786ca8b3-6915-4846-8f0f-9865fbc295f5", - "value": "Crptxxx Ransomware" - }, - { - "description": "About: This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "extensions": [ - ".enc" - ], - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes-filenames": [ - "motd.txt" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-suCNGXgzWuM/WM7HPujx_qI/AAAAAAAAEUk/gIvzbsbB_BUrBmmBsgpb_8w7zjwudu_mACLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/motd-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/642409/motd-of-ransome-hostage/", - "https://www.bleepingcomputer.com/forums/t/642409/motd-ransomware-help-support-topics-motdtxt-and-enc-extension/" - ] - }, - "uuid": "5d1a3631-165c-4091-ba55-ac8da62efadf", - "value": "MOTD Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".devil" - ], - "payment-method": "Dollars", - "price": "20 - 100", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-i5iUwC8XWDo/WM7dSVNQ8UI/AAAAAAAAEVY/uXmUErkLgHcWbfpdw1zGTvwY9DimiAH8wCLcB/s1600/lock-panel.jpg", - "https://1.bp.blogspot.com/-9ovaMSUgtFQ/WM7dXo84tlI/AAAAAAAAEVc/_Zx9gZuvHA0tU9-jtzP492bXa5fQiL7kgCLcB/s1600/key-price.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/cryptodevil-ransomware.html", - "https://twitter.com/PolarToffee/status/843527738774507522" - ] - }, - "uuid": "f3ead274-6c98-4532-b922-03d5ce4e7cfc", - "value": "CryptoDevil Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on HiddenTear", - "meta": { - "date": "February 2017", - "encryption": "AES-256+RSA", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-QuBYcLAKRPU/WLnE3Rn3MhI/AAAAAAAAEH4/WnC5Ke11j4MO7wmnfqBhtA-hpx6YN6TBgCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/fabsyscrypto-ransomware.html", - "https://twitter.com/struppigel/status/837565766073475072" - ] - }, - "uuid": "e4d36930-2e00-4583-b5f5-d8f83736d3ce", - "value": "FabSysCrypto Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES+RSA", - "extensions": [ - "[file_name.file_ext].id-[UserID]__contact_me_lock2017@protonmail.com_or_lock2017@unseen.is" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-FllHGqIx_JQ/WL1QF2uMCCI/AAAAAAAAEJQ/Fn-8j2t8dwgSo8YTHM1iOkL-3U_hbcaKwCLcB/s1600/Note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/lock2017-ransomware.html" - ] - }, - "uuid": "cf47a853-bc1d-42ae-8542-8a7433f6c9c2", - "value": "Lock2017 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".Horas-Bah" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/redants-ransomware.html" - ] - }, - "uuid": "dd3601f1-df0a-4e67-8a20-82e7ba0ed13c", - "value": "RedAnts Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/consoleapplication1-ransomware.html" - ] - }, - "uuid": "4c3788d6-30a9-4cad-af33-81f9ce3a0d4f", - "value": "ConsoleApplication1 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "March 2017", - "encryption": "AES", - "extensions": [ - ".kr3" - ], - "payment-method": "no ransom", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/krider-ransomware.html", - "https://twitter.com/malwrhunterteam/status/836995570384453632" - ] - }, - "uuid": "f5ac03f1-4f6e-43aa-836a-cc7ece40aaa7", - "value": "KRider Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. The following note is what you get if you put in the wrong key code: https://3.bp.blogspot.com/-qsS0x-tHx00/WLM3kkKWKAI/AAAAAAAAEDg/Zhy3eYf-ek8fY5uM0yHs7E0fEFg2AXG-gCLcB/s1600/failed-key.jpg", - "meta": { - "date": "February 2017", - "payment-method": "Bitcoin", - "price": "0.5 (300$)", - "refs": [ - "https://id-ransomware.blogspot.co.il/search?updated-min=2017-01-01T00:00:00-08:00&updated-max=2018-01-01T00:00:00-08:00&max-results=50" - ] - }, - "uuid": "44f6d489-f376-4416-9ba4-e153472f75fc", - "value": "CYR-Locker Ransomware (FAKE)" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes": [ - "DotRansomware Setup Guide \nAttention!!! \nWe recommend you to build your ransomware inside virtual machine! (But it is safe to use builder on your PC, just don't run builded exe file on your PC!) \nRecommendation: If you have got possibility to run ransomware on victim's computer with administrator privileges then do it. Because it will provide better conversion. Recommended decryption price: 0.1 Recommended special decryption prices: FR|0.15|FI|0.15|IE|0.15|IS|0.15|AU|0.15|BE|0.15|CA|0.15|AT|0.15|DK|0.15|SE|0.15|DE|0.15|NL|0.15|SA|0.2|US|0.2|HK|0.2|LU|0.2|CH|0.2|NO|0.2|AE|0.2|SG|0.2|KW|0.2|MO|0.2|QA|0.2 Recommended attacked extensions: *** Recommendation: You need to test builded exe file inside virtual machine, because operability can be broken after crypt/pack of core! \nLinks to website: ***" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-BoKI2-Lhsp8/WLHq34zCtdI/AAAAAAAAECo/YkfIG29vRRsLvdn51ctrMEypptRzZS2IgCLcB/s1600/raas.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/dotransomware.html" - ] - }, - "uuid": "0570e09d-10b9-448c-87fd-c1c4063e6592", - "value": "DotRansomware" - }, - { - "description": "About: This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments.All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".locked-[3_random_chars]" - ], - "payment-method": "Bitcoin", - "price": "0.01 - 0.06", - "ransomnotes-filenames": [ - "ReadMe-[3_random_chars].html" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-92aP_sumdLo/WLAy3D2kLvI/AAAAAAAAEAQ/FA1j--rOIygsNbDAWqrDqufT7zSwuEnvQCLcB/s1600/note-html_2.png", - "https://3.bp.blogspot.com/-E1vV0sqaw2o/WLB1OvOLCPI/AAAAAAAAEAg/D4OkAOBT_uM4DeVS1hAu6eBGcmga8CSYwCLcB/s1600/site1.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/unlock26-ransomware.html", - "https://www.bleepingcomputer.com/news/security/new-raas-portal-preparing-to-spread-unlock26-ransomware/" - ] - }, - "uuid": "37b9a28d-8554-4233-b130-efad4be97bc0", - "value": "Unlock26 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Python Ransomware", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".EnCrYpTeD" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "READ_ME_TO_DECRYPT.txt" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/pickles-ransomware.html", - "https://twitter.com/JakubKroustek/status/834821166116327425" - ], - "synonyms": [ - "Pickles" - ] - }, - "uuid": "87171865-9fc9-42a9-9bd4-a453f556f20c", - "value": "PicklesRansomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. This ransomware poses at MSOffice to fool users into opening the infected file. GO Ransomware", - "meta": { - "date": "February 2017", - "encryption": "ChaCha20 and Poly1305", - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "NOT YOUR LANGUAGE? https://translate.google.com Your personal files and documents have been encrypted withAES-256 and RSA-2048! Decrypting your files is only possible with decrypt key stored on our server. Price for key is % bitcoin % BTC (Bitcoin).\n1. Send % bitcoin % BTC to % bitcoinaddress % http://www.coindesk.com/information/how-can-i-buy-bitcoins/ https://www.bitcoin.com/buy-bitcoin \n2. Wait some time for transaction to process \n3. PRIVATE KEY WILL BE DOWNLOADED AND SYSTEM WILL AUTOMATICALLY DECRYPT YOUR FILES! \nIf you do not pay within % hoursvalid % hours key will become DESTROYED and your files LOST forever! Removing this software will make recovering files IMPOSSIBLE! Disable your antivirus for safety." - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/vanguard-ransomware.html", - "https://twitter.com/JAMESWT_MHT/status/834783231476166657" - ] - }, - "uuid": "6a6eed70-3f90-420b-9e4a-5cce9428dc06", - "value": "Vanguard Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "ChaCha20 and Poly1305", - "extensions": [ - ".d4nk" - ], - "ransomnotes": [ - "ATTENTION You Have Been Infected With Ransomware. Please Make Note of Your Unique Idenfier : *** " - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/pyl33t-ransomware.html", - "https://twitter.com/Jan0fficial/status/834706668466405377" - ] - }, - "uuid": "305cb1fb-d43e-4477-8edc-90b34aaf227f", - "value": "PyL33T Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. This is the old VenusLocker in disquise .To delete shadow files use the following commend: C:\\Windows\\system32\\wbem\\wmic.exe shadowcopy delete&exit https://2.bp.blogspot.com/-8qIiBHnE9yU/WK1mZn3LgwI/AAAAAAAAD-M/ZKl7_Iwr1agYtlVO3HXaUrwitcowp5_NQCLcB/s1600/lock.jpg", - "meta": { - "date": "February 2017", - "encryption": "AES-128", - "extensions": [ - ".trumplockerf", - ".TheTrumpLockerf", - ".TheTrumpLockerfp" - ], - "payment-method": "Bitcoin", - "price": "1(50 - 165$)", - "ransomnotes-filenames": [ - "What happen to my files.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/u/986406/Ransomware/TrumpLocker/TrumpLocker-wallpaper.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/new-trump-locker-ransomware-is-a-fraud-just-venuslocker-in-disguise/", - "https://id-ransomware.blogspot.co.il/2017/02/trumplocker.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-february-24th-2017-trump-locker-macos-rw-and-cryptomix/" - ] - }, - "uuid": "63bd845c-94f6-49dc-8f0c-22e6f67820f7", - "value": "TrumpLocker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Written in Delphi", - "meta": { - "date": "February 2017", - "encryption": "AES-128 OR Combination of SHA-1 and Blowfish", - "extensions": [ - ".damage" - ], - "ransomnotes": [ - "TtWGgOd57SvPlkgZ***\n ==========\n end of secret_key \nTo restore your files - send e-mail to damage@india.com" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/damage-ransomware.html", - "https://decrypter.emsisoft.com/damage", - "https://twitter.com/demonslay335/status/835664067843014656" - ] - }, - "uuid": "fbcb6a4f-1d31-4e31-bef5-e162e35649de", - "value": "Damage Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on HiddenTear", - "meta": { - "date": "February 2017", - "encryption": "AES-128", - "extensions": [ - "your files get marked with: “youarefucked”" - ], - "payment-method": "Bitcoin", - "price": "0.1 - 0.2", - "ransomnotes": [ - "All your files has been encrypted with RSA-2048 and AES-128. There is no way to decrypt without private key and decrypt program. You can buy the private key and the decrypt program just for 0.2 BTC (Bitcoin) You have 48 hours to buy it. After that, your private key will gone and we can't guarantee to decrypt.Email me for more information about how to buy it at cyberking@indonesianbacktrack.or.id" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/xyzware-ransomware.html", - "https://twitter.com/malwrhunterteam/status/833636006721122304" - ] - }, - "uuid": "f0652feb-a104-44e8-91c7-b0435253352b", - "value": "XYZWare Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES-128", - "extensions": [ - "your files get marked with: “youarefucked”" - ], - "payment-method": "Bitcoin", - "price": "0.1 (250$)", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-S0-Bop8XUgk/WLD_RVgldgI/AAAAAAAAEBU/r2LmgjTHUbMTtIKGH2pHdKfFXcUEOQdMgCLcB/s1600/lock-act2.png" - ], - "refs": [ - "https://www.enigmasoftware.com/youarefuckedransomware-removal/" - ], - "synonyms": [ - "FortuneCrypt" - ] - }, - "uuid": "912af0ef-2d78-4a90-a884-41f3c37c723b", - "value": "YouAreFucked Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. ", - "meta": { - "date": "February 2017", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "0.5 - 0.7", - "ransomnotes-filenames": [ - "How decrypt files.hta" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-M2CMU8RPgqw/WLfqOCgNXrI/AAAAAAAAEGA/W-uAf30qQgoZxqRwblUcSKzYrM5QmcLfgCLcB/s1600/note-html_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/cryptconsole-2-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/" - ] - }, - "uuid": "7343da8f-fe18-46c9-8cda-5b04fb48e97d", - "value": "CryptConsole 2.0 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on HiddenTear", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".barRex", - ".BarRax" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/barraxcrypt-ransomware.html", - "https://twitter.com/demonslay335/status/835668540367777792" - ], - "synonyms": [ - "BarRaxCrypt Ransomware" - ] - }, - "uuid": "c0ee166e-273f-4940-859c-ba6f8666247c", - "value": "BarRax Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-hvTBarxSO8Y/WKs5kjdpgDI/AAAAAAAAD9Q/m3louiSE6xY0BcGjnWvg_NNDU6K1ok3ggCLcB/s1600/lock.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/cryptolocker-by-ntk-ransomware.html" - ] - }, - "uuid": "51bcbbc6-d8e0-4d2b-b5ce-79f26d669567", - "value": "CryptoLocker by NTK Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES-256+RSA", - "extensions": [ - ".ENCR" - ], - "payment-method": "Bitcoin", - "price": "0.8 - 2", - "ransomnotes": [ - "All of your personal information, unfortunately for you, were encrypted\nStep 1 - PAYMENT\nStep 2 - Tell us\nStep 3 - Data Recovery\nYour data and files were encrypted, unfortunately, you need our key. For the encryption each key is unique AES-256 is created on the computer. At the moment, all the files are already encrypted and the keys securely stored in an encrypted form with RSA-2048. \nOnly one way you can recover your files - make payment in Bitcoins and get our key for decryption. Do not believe in any fairy tales on the Internet, it can be circumvented if it was easy, a lot of things in the world stopped working. \nPay according to the instructions, click through the tabs, and wait for your keys. We value the market professional customer service and reputation, so will try to unlock your files as soon as possible.\nPayment Amount: 0,8 BTC\nPayment Amount: 2.1 BTC (another option)" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-0D8XdlTNIsA/WLXFiBWz5II/AAAAAAAAEFQ/Hojw0BHHysUieiCnidoVwTrqXVCckLkSQCLcB/s1600/lock-screen.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/userfileslocker-ransomware.html" - ], - "synonyms": [ - "CzechoSlovak Ransomware" - ] - }, - "uuid": "c9e29151-7eda-4192-9c34-f9a81b2ef743", - "value": "UserFilesLocker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. PAYING RANSOM IS USELESS, YOUR FILES WILL NOT BE FIXED. THE DAMAGE IS PERMENENT!!!!", - "meta": { - "date": "February 2017", - "encryption": "AES-256+RSA", - "extensions": [ - ".A9v9Ahu4-000" - ], - "payment-method": "Bitcoin", - "price": "6", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017_03_01_archive.html", - "https://id-ransomware.blogspot.co.il/2017/03/avastvirusinfo-ransomware.html" - ] - }, - "uuid": "78649172-cf5b-4e8a-950b-a967ff700acf", - "value": "AvastVirusinfo Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-OCBIabrrZNg/WLm1RGFVKEI/AAAAAAAAEHY/1MASb-0Y7jsBlE2TzyqgknrfDhuEsNx2gCLcB/s1600/Screenshot_1.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/03/suchsecurity-ransomware.html" - ], - "synonyms": [ - "Such Security" - ] - }, - "uuid": "22481dfd-8284-4071-a76f-c9a4a5f43f00", - "value": "SuchSecurity Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES-256", - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-viZiAZr3_ns/WKrIDWEEBXI/AAAAAAAAD8c/8n1RJ9m2Odoe3bvMMmIm421NdxS-OIRzQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/vhd-ransomware.html" - ], - "synonyms": [ - "VHDLocker Ransomware" - ] - }, - "uuid": "9de7a1f2-cc21-40cf-b44e-c67f0262fbce", - "value": "PleaseRead Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "extensions": [ - "[KASISKI]" - ], - "payment-method": "Dollars", - "price": "500", - "ransomnotes-filenames": [ - "INSTRUCCIONES.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-ehXlWPLxtR8/WKdHF_Y-MeI/AAAAAAAAD5A/KKXO-S9OtMQAcNM-IOV2ees8qKlAJ3pzACLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/kasiski-ransomware.html", - "https://twitter.com/MarceloRivero/status/832302976744173570", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-february-17th-2017-live-hermes-reversing-and-scada-poc-ransomware/" - ] - }, - "uuid": "59b537dc-3764-42fc-a416-92d2950aaff1", - "value": "Kasiski Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "Files has been encrypted with Locky Ransomware, Do not alter your files or you will not be able to recover anything nobody will be able to recover your data since its set to AES-256 and requires our Key Send me 1.0 bitcoins Send payment to this Address: 13DYdAKb8nfo1AYeGpJXwKZYupyeqYu2QZ For Instructions on how to Purchase & send bitcoin refer to this link : *** for support Email: lockyransomware666@sigaint.net After 48 Hours your ransom doubles to 2.0 BTC After 72 Hours we will delete your recovery keys" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-locky-ransomware-encrypts-local-files-and-unmapped-network-shares/", - "https://id-ransomware.blogspot.co.il/2017/02/locky-impersonator.html", - "https://www.bleepingcomputer.com/news/security/locky-ransomware-switches-to-thor-extension-after-being-a-bad-malware/" - ], - "synonyms": [ - "Locky Impersonator Ransomware" - ] - }, - "uuid": "26a34763-a70c-4877-b99f-ae39decd2107", - "value": "Fake Locky Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. CryptoShield 1.0 is a ransomware from the CryptoMix family.", - "meta": { - "date": "January 2017", - "encryption": "AES(256)/ROT-13", - "extensions": [ - ".CRYPTOSHIELD (The name is first changed using ROT-13, and after a new extension is added.)" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "# RESTORING FILES #.txt", - "# RESTORING FILES #.html" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-A-N9zQgZrhE/WJHAHzuitvI/AAAAAAAADhI/AHkLaL9blZgqQWc-sTevVRTxVRttbugoQCLcB/s1600/note-2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/cryptoshield-2-ransomware.html", - "https://www.bleepingcomputer.com/news/security/cryptomix-variant-named-cryptoshield-1-0-ransomware-distributed-by-exploit-kits/" - ] - }, - "uuid": "1f915f16-2e2f-4681-a1e8-e146a0a4fcdf", - "value": "CryptoShield 1.0 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Filemarker: \"HERMES\"", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Email - Bitcoin", - "ransomnotes": [ - "UNIQUE_ID_DO_NOT_REMOVE" - ], - "ransomnotes-filenames": [ - "DECRYPT_INFORMATION.html" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-nzY6thZOXSk/WKbYmWxa0rI/AAAAAAAAD3s/t_3d90FGOe8je8rfeeYLF1jzJinG5JMVgCLcB/s1600/note_2_2.png", - "https://3.bp.blogspot.com/-Yisae5e5Pjs/WKbXmIXU8YI/AAAAAAAAD3g/WZs5XzL4l4snT2j4yfc3CAaF7KonH_DQACLcB/s1600/note_1.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/hermes-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-february-17th-2017-live-hermes-reversing-and-scada-poc-ransomware/", - "https://www.bleepingcomputer.com/forums/t/642019/hermes-ransomware-help-support-decrypt-informationhtml/", - "https://www.bleepingcomputer.com/news/security/hermes-ransomware-decrypted-in-live-video-by-emsisofts-fabian-wosar/" - ] - }, - "related": [ - { - "dest-uuid": "4d8da0af-cfd7-4990-b211-af0e9906eca0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b7102922-8aad-4b29-8518-6d87c3ba45bb", - "value": "Hermes Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".hasp" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-YdCKWLUFBOo/WKRCD2BLzTI/AAAAAAAAD14/BPtYMLvQpEMAbT-ZdiCVPi_LZCrXYJMhwCLcB/s1600/ReadME%2521.txt.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/lovelock-ransomware.html" - ], - "synonyms": [ - "LoveLock", - "Love2Lock" - ] - }, - "uuid": "0785bdda-7cd8-4529-b28e-787367c50298", - "value": "LoveLock Ransomware or Love2Lock Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".wcry" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-iUq492KUatk/WKH-GXnO4-I/AAAAAAAADzw/9uwo1LF5ciIvMJ6jAn3mskSqtdiTkxvlACLcB/s1600/lock-note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/wcry-ransomware.html" - ] - }, - "uuid": "0983bdda-c637-4ad9-a56f-615b2b052740", - "value": "Wcry Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "0,3169", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-_Udncaac_gM/WKROBN00ORI/AAAAAAAAD2U/HsHkEspG85YSfPg-8MbPYYTYmBU4PAJAgCLcB/s1600/note_2.png", - "https://4.bp.blogspot.com/-Vx9ZtCODajg/WKiMr2QX5cI/AAAAAAAAD64/QAh37o_CRIImaxUfIhoEh8qE4JLn5HaNwCLcB/s1600/dumb.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/dumb-ransomware.html", - "https://twitter.com/bleepincomputer/status/816053140147597312?lang=en" - ] - }, - "uuid": "27feba66-e9c7-4414-a560-1e5b7da74d08", - "value": "DUMB Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "February 2017", - "encryption": "AES", - "extensions": [ - ".b0C", - ".b0C.x" - ], - "payment-method": "Bitcoin", - "price": "0,2", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017_02_01_archive.html", - "https://id-ransomware.blogspot.co.il/2017/02/x-files-ransomware.html" - ] - }, - "uuid": "c24f48ca-060b-4164-aafe-df7b3f43f40e", - "value": "X-Files" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The Ransom is 249$ and the hacker demands that the victim gets in contact through e-mail and a Polish messenger called Gadu-Gadu.", - "meta": { - "date": "February 2017", - "encryption": "AES-256", - "extensions": [ - ".aes" - ], - "payment-method": "Dollars", - "price": "249", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-ahpZEI1FHQM/WJd7_dpYlyI/AAAAAAAADm8/4-nFXqc9bjEI93VDJRdsLSlBOwQiaM7swCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/polski-ransomware.html" - ] - }, - "uuid": "b50265ac-ee45-4f5a-aca1-fabe3157fc14", - "value": "Polski Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. This hacker demands that the victim contacts him through email and decrypts the files for FREE.(moreinfo in the link below)", - "meta": { - "date": "February 2016", - "encryption": "AES-256", - "extensions": [ - ".yourransom" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "README.txt" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-dFQlF_6uTkI/WJYigC5GwiI/AAAAAAAADlk/jm-ZwqJ2mVYd2gtAQgYW_lOd78u5N2x0ACLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/yourransom-ransomware.html", - "https://www.bleepingcomputer.com/news/security/yourransom-is-the-latest-in-a-long-line-of-prank-and-educational-ransomware/", - "https://twitter.com/_ddoxer/status/827555507741274113" - ] - }, - "uuid": "908b914b-6744-4e16-b014-121cf2106b5f", - "value": "YourRansom Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ranion Raas gives the opportunity to regular people to buy and distribute ransomware for a very cheap price. (More info in the link below). RaaS service", - "meta": { - "date": "February 2016", - "encryption": "AES-256", - "payment-method": "Bitcoin", - "price": "0.6 - 0.95", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-ORiqmM6oWXc/WJV7X4IvTWI/AAAAAAAADlE/wXvz5Hsv1gQ-UrLoA1plVjLTVD7iDDxwQCLcB/s1600/buy_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/ranion-raas.html", - "https://www.bleepingcomputer.com/news/security/ranion-ransomware-as-a-service-available-on-the-dark-web-for-educational-purposes/" - ] - }, - "uuid": "b4de724f-add4-4095-aa5a-e4d039322b59", - "value": "Ranion RaasRansomware" - }, - { - "description": "Wants a ransom to get the victim’s files back . Originated in English. Spread worldwide.", - "meta": { - "date": "January 2017", - "encryption": "AES-256", - "extensions": [ - ".potato" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "How to recover my files.txt", - "README.png", - "README.html" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-E9GDxEoz95k/WIop79nWZ2I/AAAAAAAADZU/CnsvOl96yesoH07BZ2Q05Fp40kLcTMmqQCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/polato-ransomware.html" - ] - }, - "uuid": "378cb77c-bb89-4d32-bef9-1b132343f3fe", - "value": "Potato Ransomware" - }, - { - "description": "This ransomware is originated in English, therefore could be used worldwide. Ransomware is spread with the help of email spam, fake ads, fake updates, infected install files.", - "meta": { - "date": "December 2016/January 2017", - "encryption": "RC4", - "extensions": [ - ".-opentoyou@india.com" - ], - "payment-method": "Email", - "ransomnotes": [ - "Your files are encrypted! To decrypt write on email - opentoyou@india.comIdentification key - 5E1C0884" - ], - "ransomnotes-filenames": [ - "!!!.txt", - "1.bmp", - "1.jpg" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-RPeHrC9Trqk/WGk1kQlBQQI/AAAAAAAAC6o/FutnWrlUf44hq54_xI_6Uz2migCR0rwlwCLcB/s1600/Note-wallp.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/opentodecrypt-ransomware.html" - ] - }, - "uuid": "e290fa29-6fc1-4fb5-ac98-44350e508bc1", - "value": "of Ransomware: OpenToYou (Formerly known as OpenToDecrypt)" - }, - { - "description": "Author of this ransomware is sergej. Ransom is 0.25 bitcoins for the return of files. Originated in English. Used worldwide. This ransomware is spread with the help of email spam, fake ads, fake updates, infected install files.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "0.25", - "ransomnotes": [ - "YOUR FILES ARE ENCRYPTED!!! To restore (decrypt) them you must:\n1. Pay 0.25 bitcoin (btc) to address 36QLSB*** You can get BTC on this site http://localbitcoins.com \n2. After payment you must send Bitcoin Transacation ID to E-mail: andresaha82@gmail.com Then we will send you decryption tool." - ], - "ransomnotes-filenames": [ - "YOUR FILES ARE ENCRYPTED!!!.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-uIb_TdWTk3Q/WI2qRSlsXJI/AAAAAAAADcE/h92XEY6AraQMUwEIOBZ9moxN1J2So8xpwCLcB/s1600/note_2.png" - ], - "refs": [ - "http://www.2-spyware.com/remove-ransomplus-ransomware-virus.html", - "https://id-ransomware.blogspot.co.il/2017/01/ransomplus-ransomware.html", - "https://twitter.com/jiriatvirlab/status/825411602535088129" - ] - }, - "uuid": "c039a50b-f5f9-4ad0-8b66-e1d8cc86717b", - "value": "RansomPlus" - }, - { - "description": "This ransomware does not actually encrypt your file, but only changes the names of your files, just like Globe Ransomware. This ransomware is spread with the help of email spam, fake ads, fake updates, infected install files", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".unCrypte@outlook.com_<random_numbers_and_upper_alphabetic_characters> ", - ".decipher_ne@outlook.com_<random_numbers_and_upper_alphabetic_characters" - ], - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes": [ - "Your files are encrypted! Your personal ID764F6A6664514B414373673170615339554A534A5832546A55487169644B4A35 Discovered a serious vulnerability in your network security. No data was stolen and no one will be able to do it while they are encrypted. For you we have automatic decryptor and instructions for remediation. How to get the automatic decryptor : \n1) Pay 0,25 BTC Buy BTC on one of these sites: https://localbitcoins.com https://www.coinbase.com https://xchange.cc bitcoin adress for pay: 1KG8rWYWRYHfvjVe8ddEyJNCg6HxVWYSQm Send 0,25 BTC \n2) Send screenshot of payment to unCrypte@outlook.com. In the letter include your personal ID (look at the beginning of this document). \n3) You will receive automatic decryptor and all files will be restored \n* To be sure in getting the decryption, you can send one file (less than 10MB) to unCrypte@outlook.com In the letter include your personal ID (look at the beginning of this document). But this action will increase the cost of the automatic decryptor on 0,25 btc... \nAttention! \n• No Payment = No decryption \n• You really get the decryptor after payment \n• Do not attempt to remove the program or run the anti-virus tools \n• Attempts to self-decrypting files will result in the loss of your data \n• Decoders other users are not compatible with your data, because each user's unique encryption key" - ], - "ransomnotes-filenames": [ - "How decrypt files.hta" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/cryptconsole-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/638344/cryptconsole-uncrypteoutlookcom-support-topic-how-decrypt-fileshta/", - "https://twitter.com/PolarToffee/status/824705553201057794", - "https://twitter.com/demonslay335/status/1004351990493741057", - "https://twitter.com/demonslay335/status/1004803373747572736" - ] - }, - "uuid": "42508fd8-3c2d-44b2-9b74-33c5d82b297d", - "value": "CryptConsole" - }, - { - "description": "Originated in English, could affect users worldwide, however so far only reports from Saudi Arabia. The malware name founded by a windows server tools is called win32/wagcrypt.A", - "meta": { - "date": "January 2017", - "extensions": [ - ".zxz" - ], - "payment-method": "Email", - "refs": [ - "https://www.bleepingcomputer.com/forums/t/638191/zxz-ransomware-support-help-topic-zxz/?hl=%2Bzxz#entry4168310", - "https://id-ransomware.blogspot.co.il/2017/01/zxz-ransomware.html" - ] - }, - "uuid": "e4932d1c-2f97-474d-957e-c7df87f9591e", - "value": "ZXZ Ramsomware" - }, - { - "description": "Developed in Visual Studios in 2010. Original name is VxCrypt. This ransomware encrypts your files, including photos, music, MS office, Open Office, PDF… etc", - "meta": { - "date": "January 2017", - "encryption": "AES+RSA", - "extensions": [ - ".vxlock" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/vxlock-ransomware.html" - ] - }, - "uuid": "14deb95c-7af3-4fb1-b2c1-71087e1bb156", - "value": "VxLock Ransomware" - }, - { - "description": "Funfact uses an open code for GNU Privacy Guard (GnuPG), then asks to email them to find out the amout of bitcoin to send (to receive a decrypt code). Written in English, can attach all over the world. The ransom is 1.22038 BTC, which is 1100USD.", - "meta": { - "date": "January 2017", - "encryption": "AES+RSA", - "payment-method": "Bitcoin", - "price": "0,65806", - "ransomnotes": [ - "Important Information!!!! You had bad luck. All your files are encrypted with RSA and AES ciphers. to get your files back read carefully. if you do not understand, Read again. All your documents are recoverable only with our software and key file. To decrypt files you need to contact worldfunfact@sigaint.org or funfacts11@tutanota.com and set your ID as email title and send clsign.dll file from your computer. That is the key file and yes, it’s encrypted. Search your computer for filename “clsign.dll” attach it to email. if you wish we will decrypt one of your encrypted file for free! It’s your guarantee. After you made payment you will receive decryption software with key and necessary instructions. if you don’t contact us within 72 hours we will turn on sanctions. you’ll have to pay more. Recovery is only possible during 7 days. after that don’t contact us. Remember you are just single payment away from all your files If your files are urgent pay exactly requested amount to Bitcoin (BTC) address and send clsign.dll file to us. We will send your decryption software within 24 hours; remember if you contact us first maybe you’ll have to pay less\nUser ID: 658061***\nBTC Address: 1AQrj***\nAmount(BTC): 1.65806\n-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion:\nGnuPG\nv2\n*******************************\n-----END PGP PUBLIC KEY BLOCK-----" - ], - "ransomnotes-filenames": [ - "note.iti" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/funfact.html", - "http://www.enigmasoftware.com/funfactransomware-removal/" - ] - }, - "uuid": "2bfac605-a2c5-4742-92a2-279a08a4c575", - "value": "FunFact Ransomware" - }, - { - "description": "First spotted in May 2016, however made a big comeback in January 2017. It’s directed to English speaking users, therefore is able to infect worldwide. Ransomware is spread with the help of email spam, fake ads, fake updates, infected install files.", - "meta": { - "date": "January 2017", - "encryption": "AES+RSA", - "extensions": [ - ".<7_random_letters>" - ], - "payment-method": "Email", - "ransomnotes": [ - "WARNING! Your personal files are encrypted! Your most important files on this computer have been encrypted: photos, documents, videos, music, etc. You can verify this by trying to open such files. Encryption was produced using an UNIQUE public RSA-4096 key, specially generated for this computer only, thus making it impossible to decrypt such files without knowing private key and comprehensive decipher software. We have left on our server a copy of the private key, along with all required software for the decryption. To make sure that software is working as intended you have a possibility to decrypt one file for free, see contacts below. The private key will be destroyed after 7 days, afterwards making it impossible to decrypt your files. Encryption date: *** Private key destruction date: *** For obtaining decryption software, please, contact: myserverdoctor@gmail.com or XMPP jabber: doctordisk@jabbim.com" - ], - "ransomnotes-filenames": [ - "encrypted_readme.txt", - "__encrypted_readme.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-CLo4JTpveKY/WI4sVXEQSPI/AAAAAAAADcU/n8qrwehDEQMlG845cjNow_fC4PDqlvPIQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/06/zekwacrypt-ransomware.html", - "http://www.2-spyware.com/remove-zekwacrypt-ransomware-virus.html" - ] - }, - "uuid": "89d5a541-ef9a-4b18-ac04-2e1384031a2d", - "value": "ZekwaCrypt Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. This ransomware attacks your MS Office by offering a Micro to help with your program, but instead incrypts all your files if the used id not protected. Predecessor CryLocker", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".sage" - ], - "payment-method": "Bitcoin", - "price": "2,15555 (2000$)", - "ransomnotes-filenames": [ - "!Recovery_[3_random_chars].html" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-6YhxRaqa_9Q/WISA9dW31bI/AAAAAAAADUE/78mNNKpPMyc2Gzi1N9CooyQp7RNT40NNgCLcB/s1600/note1_2.png", - "https://1.bp.blogspot.com/-_c5vGu4nCvE/WIT_pWP_FSI/AAAAAAAADUs/8hK8a4E48sY3U_aAHC2qNzYDBL0bQcNjgCLcB/s1600/note-wallp111.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/sage-2-ransomware.html", - "https://isc.sans.edu/forums/diary/Sage+20+Ransomware/21959/", - "http://www.securityweek.com/sage-20-ransomware-demands-2000-ransom", - "https://www.bleepingcomputer.com/news/security/sage-2-0-ransomware-gearing-up-for-possible-greater-distribution/", - "https://www.govcert.admin.ch/blog/27/sage-2.0-comes-with-ip-generation-algorithm-ipga" - ] - }, - "uuid": "9174eef3-65f7-4ab5-9b55-b323b36fb962", - "value": "Sage 2.0 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. Uses the name “Window Update” to confuse its victims. Then imitates the window update process , while turning off the Window Startup Repair and changes the BootStatusPolicy using these commands: bcdedit.exe /set {default} recoveryenabled No bcdedit.exe /set {default} bootstatuspolicy ignoreallfailures", - "meta": { - "date": "January 2017", - "encryption": "AES", - "payment-method": "Bitcoin", - "ransomnotes-filenames": [ - "Warning警告.html" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-OTxFEWf7LiY/WIO0rJmBgJI/AAAAAAAADTQ/U3BLcd2-CPQQ_73eIKIyg28cKFmw4nctgCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/cloudsword.html", - "http://bestsecuritysearch.com/cloudsword-ransomware-virus-removal-steps-protection-updates/", - "https://twitter.com/BleepinComputer/status/822653335681593345" - ] - }, - "uuid": "a89e0ae0-e0e2-40c5-83ff-5fd672aaa2a4", - "value": "CloudSword Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. Uses the name “Chrome Update” to confuse its victims. Then imitates the chrome update process ,while encrypting the files. DO NOT pay the ransom, since YOUR COMPUTER WILL NOT BE RESTORED FROM THIS MALWARE!!!!", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".killedXXX" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-llR46G5zOBE/WIJuTTHImXI/AAAAAAAADS8/Ww_QU1Z7Q3geZgiSStJB3siO3oQJpIcowCLcB/s1600/note.jpg", - "https://4.bp.blogspot.com/-ilIaUD5qOuk/WIJuV1TuC1I/AAAAAAAADTA/SOj8St_qXMsgDexK1BGgZT0yFDkNDz_7QCLcB/s1600/lock.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/dn-donotopen.html" - ], - "synonyms": [ - "Fake" - ] - }, - "uuid": "327eb8b4-5793-42f0-96c0-7f651a0debdc", - "value": "DN" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. Its original name is FileSpy and FileSpy Application. It is spread using email spam, fake updates, infected attachments and so on. It encryps all your files, including: music, MS Office, etc..", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".id-_garryweber@protonmail.ch" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "HOW_OPEN_FILES.html" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-w6lxK0qHj8A/WIO_iAngUzI/AAAAAAAADTk/dLGlrwwOh508AlG2ojLRszpUxL0tHrtSQCLcB/s1600/note-html.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/garryweber.html" - ] - }, - "uuid": "b6e6da33-bf23-4586-81cf-dcfe10e13a81", - "value": "GarryWeber Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. Its original name is RAAS RANSOMWARE. It is spread using email spam, fake updates, infected attachments and so on. It encryps all your files, including: music, MS Office, Open Office, pictures etc.. This ransomware promotes other to download viruses and spread them as ransomware to infect other users and keep 70% of the ransom. (leaving the other 30% to Satan) https://3.bp.blogspot.com/-7fwX40eYL18/WH-tfpNjDgI/AAAAAAAADPk/KVP_ji8lR0gENCMYhb324mfzIFFpiaOwACLcB/s1600/site-raas.gif RaaS", - "meta": { - "date": "January 2017", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - ".stn" - ], - "payment-method": "Bitcoin", - "price": "0.1 - your choice", - "ransomnotes-filenames": [ - "HELP_DECRYPT_FILES.html" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-5BgSHIym-8Y/WIH92q4ymHI/AAAAAAAADSk/MF2T-mmhuY4irQZFqmpGZjmUI2onlNCyACLcB/s1600/ransom-note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/satan-raas.html", - "https://www.bleepingcomputer.com/forums/t/637811/satan-ransomware-help-support-topic-stn-extension-help-decrypt-fileshtml/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-january-20th-2017-satan-raas-spora-locky-and-more/", - "https://www.bleepingcomputer.com/news/security/new-satan-ransomware-available-through-a-ransomware-as-a-service-/", - "https://twitter.com/Xylit0l/status/821757718885236740" - ] - }, - "related": [ - { - "dest-uuid": "5639f7db-ab70-4b86-8a2f-9c4e3927ba91", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "61d8bba8-7b22-493f-b023-97ffe7f17caf", - "value": "Satan Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, infected attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures , videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".HavocCrypt" - ], - "payment-method": "Bitcoin", - "price": "150 $", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-Xs7yigomWw8/WH0mqn0QJLI/AAAAAAAADKA/0Fk5QroMsgQ3AsXbHsbVtopcJN4qzDgdACLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/havoc-ransomware.html" - ], - "synonyms": [ - "HavocCrypt Ransomware" - ] - }, - "uuid": "c6bef9c8-becb-4bee-bd97-c1c655133396", - "value": "Havoc" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Its fake name is Bitcoin and maker’s name is Santiago. Work of the encrypted requires the user to have .NET Framework 4.5.2. on his computer.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "IMPORTANTE_LEER.html", - "RECUPERAR_ARCHIVOS.html" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-KE6dziEK4To/WHnvPzKOs7I/AAAAAAAADHI/KPBjmO9iChgAa12-f1VOxF49Pv27-0XfQCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/cryptosweettooth.html", - "http://sensorstechforum.com/remove-cryptosweettooth-ransomware-restore-locked-files/" - ] - }, - "uuid": "ca831782-fcbf-4984-b04e-d79b14e48a71", - "value": "CryptoSweetTooth Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The word Kaandsona is Estonian, therefore the creator is probably from Estonia. Crashes before it encrypts", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".kencf" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "You have been struck by the holy Kaandsona ransomware Either you pay 1 BTC in 24 hours or you lose ALL FILES \nbutton 'Show all encrypted files' \nbutton 'PAY'" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-v3jncd77m3U/WHkjPoEusKI/AAAAAAAADGE/xJOIgzm-ST0L4kpNeThKTyfukq3e1Th-QCLcB/s1600/troll-22.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/kaandsona-ransomtroll.html", - "https://twitter.com/BleepinComputer/status/819927858437099520" - ], - "synonyms": [ - "RansomTroll Ransomware", - "Käändsõna Ransomware" - ] - }, - "uuid": "aed61a0a-dc48-43ac-9c33-27e5a286899e", - "value": "Kaandsona Ransomware" - }, - { - "description": "It’s directed to English and Chinese speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Python Ransomware", - "meta": { - "date": "January 2017", - "encryption": "AES-256", - "extensions": [ - ".lambda_l0cked" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1", - "ransomnotes-filenames": [ - "READ_IT.hTmL" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-B3o6bGziu_M/WHkyueI902I/AAAAAAAADGw/la7psCE9JEEe17GipFh69xVnIDYGFF38wCLcB/s1600/note-1-2.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/lambdalocker.html", - "http://cfoc.org/how-to-restore-files-affected-by-the-lambdalocker-ransomware/" - ] - }, - "uuid": "0d1b35e9-c87a-4972-8c27-a11c13e351d7", - "value": "LambdaLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".HakunaMatata" - ], - "payment-method": "Website (onion)", - "ransomnotes-filenames": [ - "Recovers files yako.html" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-DUXeyyzqwKs/WHkrGvLyFvI/AAAAAAAADGg/SPfrNMZYGs8edE7X5z-3MBroIqS5GQ8kACLcB/s1600/note_1-str_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/hakunamatata.html", - "https://id-ransomware.blogspot.co.il/2016_03_01_archive.html" - ], - "synonyms": [ - "HakunaMatataRansomware" - ] - }, - "uuid": "0645cae2-bda9-4d68-8bc3-c3c1eb9d1801", - "value": "NMoreia 2.0 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is .2 bitcoin, however there is no point of even trying to pay, since this damage is irreversible. Once the ransom is paid the hacker does not return decrypt the files. Another name is DeMarlboro and it is written in language C++. Pretend to encrypt using RSA-2048 and AES-128 (really it’s just XOR)", - "meta": { - "date": "January 2017", - "encryption": "XOR", - "extensions": [ - ".oops" - ], - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes-filenames": [ - "_HELP_Recover_Files_.html" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-7UmhPM2VSKY/WHe5tDsHfuI/AAAAAAAADFM/FRdUnAyxAggvF0hX0adtrpq48F7HXPbawCLcB/s1600/check-decrypt.png", - "https://1.bp.blogspot.com/-MWRTa6aXtdk/WHflJFyb-GI/AAAAAAAADFs/dc-l-RrWSCAPE8akw2SCb1uuj-a-2shiwCLcB/s1600/docm.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/marlboro.html", - "https://decrypter.emsisoft.com/marlboro", - "https://www.bleepingcomputer.com/news/security/marlboro-ransomware-defeated-in-one-day/" - ] - }, - "uuid": "4ae98da3-c667-4c6e-b0fb-5b52c667637c", - "value": "Marlboro Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Sample of a spam email with a viral attachment: https://4.bp.blogspot.com/-KkJXiHG80S0/WHX4TBpkamI/AAAAAAAADDg/F_bN796ndMYnzfUsgSWMXhRxFf3Ic-HtACLcB/s1600/spam-email.png", - "meta": { - "date": "January 2017", - "encryption": "AES+RSA", - "payment-method": "Bitcoin", - "price": "79$", - "ransomnotes-filenames": [ - "[Infection-ID].HTML" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-0COE3ADdaYk/WHpnHzuo7OI/AAAAAAAADHY/yfDF3XG720Yyn3xQHwFngt1T99cT-Xt3wCLcB/s1600/rus-note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/spora-ransomware.html", - "https://blog.gdatasoftware.com/2017/01/29442-spora-worm-and-ransomware", - "http://blog.emsisoft.com/2017/01/10/from-darknet-with-love-meet-spora-ransomware/" - ] - }, - "uuid": "46601172-d938-47af-8cf5-c5a796ab68ab", - "value": "Spora Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The files get encrypted, but the decrypt key is not available. NO POINT OF PAYING THE RANSOM, THE FILES WILL NOT BE RETURNED.", - "meta": { - "date": "January 2017", - "encryption": "AES+RSA", - "extensions": [ - ".crypto" - ], - "payment-method": "Bitcoin", - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/cryptokill-ransomware.html" - ] - }, - "uuid": "7ae2f594-8a72-4ba8-a37a-32457d1d3fe8", - "value": "CryptoKill Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "extensions": [ - "AES+RSA" - ], - "payment-method": "Bitcoin", - "price": "0.35", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-mwIvQNkFH4g/WKAydZnGn_I/AAAAAAAADxs/6xHgbD3OUFUbebeuNVkI6tp_cMRVUQHtQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/allyourdocuments-ransomware.html" - ] - }, - "uuid": "62120e20-21f6-474b-9dc1-fc871d25c798", - "value": "All_Your_Documents Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The ransom is 500$ in bitcoins. The name of the hacker is R4z0rx0r Serbian Hacker.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".velikasrbija" - ], - "payment-method": "Bitcoin", - "price": "500$", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-OY8jgTN5Y9Q/WKAI6a9xfMI/AAAAAAAADwc/ng36hAXsvfYQ5rdkSFeVgEvLY88pJmnWACLcB/s1600/note-html-wallp.jpg", - "https://3.bp.blogspot.com/-DQQ5tk0C9lY/WKALND0dYPI/AAAAAAAADwo/EuKiO_F0Mn0ImrGLVE-Sks-j93pHoTjKACLcB/s1600/konstr.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/serbransom-2017.html", - "https://www.bleepingcomputer.com/news/security/ultranationalist-developer-behind-serbransom-ransomware/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-february-10th-2017-serpent-spora-id-ransomware/", - "https://twitter.com/malwrhunterteam/status/830116190873849856" - ] - }, - "uuid": "fb1e99cb-73fa-4961-a052-c90b3f383542", - "value": "SerbRansom 2017 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The ransom is 0.33 bitcoins.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "0.33", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-5t-5eBl4Tng/WKARmYV5GVI/AAAAAAAADxA/OuS7Eo__z1sh2tRbBpQIxJQ6IVbSiQakwCLcB/s1600/lock-note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/fadesoft-ransomware.html", - "https://twitter.com/malwrhunterteam/status/829768819031805953", - "https://twitter.com/malwrhunterteam/status/838700700586684416" - ] - }, - "uuid": "ccfe7f6a-9c9b-450a-a4c7-5bbaf4a82e37", - "value": "Fadesoft Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - ".encypted" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-kolk6sABFzQ/WJ95ddcAxNI/AAAAAAAADwI/oP8ZFD7KnqoQWgpfgEHId843x3l0xfhjACLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/hugeme-ransomware.html", - "https://www.ozbargain.com.au/node/228888?page=3", - "https://id-ransomware.blogspot.co.il/2016/04/magic-ransomware.html" - ] - }, - "uuid": "681ad7cc-fda0-40dc-83b3-91fdfdec81e1", - "value": "HugeMe Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - ".crypt" - ], - "payment-method": "Bitcoin", - "price": "50$", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-Qx8RhielSbI/WJypR9Zw9nI/AAAAAAAADus/Opsfy8FxRIIBmouywdl7uT94ZpfwKr6JACLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/dyna-crypt-ransomware.html", - "https://www.bleepingcomputer.com/news/security/dyna-crypt-not-only-encrypts-your-files-but-also-steals-your-info/" - ], - "synonyms": [ - "DynA CryptoLocker Ransomware" - ] - }, - "uuid": "9979ae53-98f7-49a2-aa1e-276973c2b44f", - "value": "DynA-Crypt Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - ".crypt" - ], - "payment-method": "Bitcoin", - "price": "0.75 (787.09$) - 2.25 (2366.55$ after 7 days)", - "ransomnotes": [ - "==== NEED HELP WITH TRANSLATE? USE https://translate.google.com ====\n================ PLEASE READ THIS MESSAGE CAREFULLY ================\n Your documents, photos, videos, databases and other important files have been encrypted! The files have been encrypted using AES256 and RSA2048 encryption (unbreakable) To decrypt your files you need to buy the special software 'SerpentDecrypter'.You can buy this software on one of the websites below. xxxx://vdpbkmwbnp.pw/00000000-00000000-00000000-00000000 xxxx://hnxrvobhgm.pw/00000000-00000000-00000000-00000000 If the websites above do not work you can use a special website on the TOR network. Follow the steps below\n1. Download the TOR browser https://www.torproject.org/projects/torbrowser.html.en#downloads\n2. Inside the TOR browser brower navigate to : 3o4kqe6khkfgx25g.onion/00000000-00000000-00000000-00000000 \n3. Follow the instructions to buy 'Serpent Decrypter'\n================ PLEASE READ THIS MESSAGE CAREFULLY ================" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/serpent-danish-ransomware.html" - ], - "synonyms": [ - "Serpent Danish Ransomware" - ] - }, - "uuid": "3b472aac-085b-409e-89f1-e8c766f7c401", - "value": "Serpent 2017 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "ROT-23", - "payment-method": "Bitcoin", - "price": "0.085", - "ransomnotes-filenames": [ - "README.HTML" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-tAp9wE6CJxM/WJrvOOyIfRI/AAAAAAAADts/iMfaiDRyRcQuPXgtQV--qt7q8ZI3ZV0tQCLcB/s1600/note1%252B.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/erebus-2017-ransomware.html", - "https://www.bleepingcomputer.com/news/security/erebus-ransomware-utilizes-a-uac-bypass-and-request-a-90-ransom-payment/" - ] - }, - "uuid": "c21e637c-6611-47e1-a191-571409b6669a", - "value": "Erebus 2017 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.085", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-7KRVg6kt418/WJnwxDOV5NI/AAAAAAAADrk/or9DbPMl-7ksN7OwIAH6BMJwE5fGc_BfgCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/ransomuhahawhere.html" - ], - "synonyms": [ - "Ransomuhahawhere" - ] - }, - "uuid": "dcb183d1-11b5-464c-893a-21e132cb7b51", - "value": "Cyber Drill Exercise " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. This is a trollware that does not encrypt your files but makes your computer act crazy (like in the video in the link below). It is meant to be annoying and it is hard to erase from your PC, but possible.", - "meta": { - "date": "February 2017", - "extensions": [ - ".cancer" - ], - "payment-method": "no ransom", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-ozPs6mwKfEI/WJjTwbrOx9I/AAAAAAAADqE/4gewG-f_dLQQDevajtn8CnX69lvWgCZQACLcB/s1600/wallp.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/cancer-ransomware.html", - "https://www.bleepingcomputer.com/news/security/watch-your-computer-go-bonkers-with-cancer-trollware/" - ] - }, - "uuid": "ef747d7f-894e-4c0c-ac0f-3fa1ef3ef17f", - "value": "Cancer Ransomware FAKE" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Poses as Microsoft Copyright 2017 and requests ransom in bitcoins.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Email - Bitcoin", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-BOmKmroIvEI/WJn-LAUmyyI/AAAAAAAADsI/W987TEaOnEAd45AOxO1cFyFvxEx_RfehgCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/02/updatehost-ransomware.html", - "https://www.bleepingcomputer.com/startups/Windows_Update_Host-16362.html" - ] - }, - "uuid": "ed5b30b0-2949-410a-bc4c-3d90de93d033", - "value": "UpdateHost Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 10 bitcoins.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".v8dp" - ], - "payment-method": "Bitcoin", - "price": "10", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-dLSbqOiIbLU/WHPh-akYinI/AAAAAAAADC0/6nFQClDBJ5M7ZhrjkhnxfkdboOh7SlE-ACLcB/s1600/v5YZMxt.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/nemesis-ransomware.html" - ] - }, - "uuid": "b5942085-c9f2-4d1a-aadf-1061ad38fb1d", - "value": "Nemesis Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Domain KZ is used, therefore it is assumed that the decrypter is from Kazakhstan. Coded in Javascript", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".file0locked", - ".evillock" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "HOW_TO_DECRYPT_YOUR_FILES.TXT", - "HOW_TO_DECRYPT_YOUR_FILES.HTML" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-0NFy_yDghZ0/WHO_ClbPdMI/AAAAAAAADCQ/RX2cgYg3z381gro6UUQtAED7JgXHbvGLgCLcB/s1600/note-txt_2.png", - "https://4.bp.blogspot.com/-xxJ9xdRuWis/WHO_FL-hWcI/AAAAAAAADCU/VqI02AhzopQY1WKk-k6QYSdHFWFzg1NcACLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/evil-ransomware.html", - "http://www.enigmasoftware.com/evilransomware-removal/", - "http://usproins.com/evil-ransomware-is-lurking/", - "https://twitter.com/jiriatvirlab/status/818443491713884161", - "https://twitter.com/PolarToffee/status/826508611878793219" - ], - "synonyms": [ - "File0Locked KZ Ransomware" - ] - }, - "uuid": "57933295-4a0e-4f6a-b06b-36807ff150cd", - "value": "Evil Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. This is a fake ransomware. Your files are not really encrypted, however the attacker does ask for a ransom of .03 bitcoins. It is still dangerous even though it is fake, he still go through to your computer.", - "meta": { - "date": "January 2017", - "payment-method": "Bitcoin", - "price": "0.03", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-3iMAtqvAmts/WHEyA_dW5OI/AAAAAAAADAY/tE5FtaVMJcc3aQQvWI4XOdjtvbXufFgywCLcB/s1600/lock1.jpg", - "https://3.bp.blogspot.com/-DMxJm5GT0VY/WHEyEOi_vZI/AAAAAAAADAc/6Zi3IBuBz1I7jdQHcSrzhUGagGCUfs6iACLcB/s1600/lock2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/ocelot-ransomware.html", - "https://twitter.com/malwrhunterteam/status/817648547231371264" - ], - "synonyms": [ - "Ocelot Locker Ransomware" - ] - }, - "uuid": "054b9fbd-72fa-464f-a683-a69ab3936d69", - "value": "Ocelot Ransomware (FAKE RANSOMWARE)" - }, - { - "description": "It’s directed to Czechoslovakianspeaking users. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on HiddenTear", - "meta": { - "date": "January 2017", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "1000 CZK", - "ransomnotes-filenames": [ - "INFOK1.txt" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-i4ksJq-UzX8/WHFFXQL5wAI/AAAAAAAADA8/awfsqj1lr7IMBAPtE0tB44PNf1N6zkGDwCLcB/s1600/note_2.png", - "https://1.bp.blogspot.com/-OlKgHvtAUHg/WHFDCx4thaI/AAAAAAAADAw/wzBXV17Xh-saaFGlrxw3CDNhGSTaVe2dQCLcB/s1600/lock1.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/skyname-ransomware.html", - "https://twitter.com/malwrhunterteam/status/817079028725190656" - ], - "synonyms": [ - "Blablabla Ransomware" - ] - }, - "uuid": "00b8ff33-1504-49a4-a025-b761738eed68", - "value": "SkyName Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 155$ inbitcoins. Creator of ransomware is called Mafia. Based on HiddenTear", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".locked-by-mafia" - ], - "payment-method": "Bitcoin", - "price": "155$", - "ransomnotes-filenames": [ - "READ_ME.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-BclLp7x1sUM/WG6acqtDBbI/AAAAAAAAC_I/ToVEXx-G2DcKD4d7TZ0RkVqA1wRicxnZQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/mafiaware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-january-6th-2017-fsociety-mongodb-pseudo-darkleech-and-more/", - "https://twitter.com/BleepinComputer/status/817069320937345024" - ], - "synonyms": [ - "Depsex Ransomware" - ] - }, - "uuid": "e5a60429-ae5d-46f4-a731-da9e2fcf8b92", - "value": "MafiaWare Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 3 bitcoins. Extesion depends on the config file. It seems Globe is a ransomware kit.", - "meta": { - "date": "January 2017", - "encryption": "AES-256+RSA or RC4", - "extensions": [ - ".badnews", - ".globe", - ".[random].bit", - ".[random].encrypted", - ".[random].raid10", - ".[random].globe", - ".[mia.kokers@aol.com]", - ".unlockv@india.com", - ".rescuers@india.com.3392cYAn548QZeUf.lock", - ".locked", - ".decrypt2017", - ".hnumkhotep" - ], - "payment-method": "Bitcoin", - "price": "3", - "ransomnotes-filenames": [ - "How To Recover Encrypted Files.hta" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-Wk1_IdcEHbk/WG6FVnoaKlI/AAAAAAAAC-4/WeHzJAUJ0goxxuAoGUUebSgzGHrnD6LQQCLcB/s1600/Globe-ransom-note_2.png.png", - "https://3.bp.blogspot.com/-lYkopoRH0wQ/WHOt1KhhzhI/AAAAAAAADCA/nPdhHK3wEucAK1GHodeh5w3HcpdugzSHwCLcB/s1600/globe3-9-1-17.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/globe3-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/624518/globe-ransomware-help-and-support-purge-extension-how-to-restore-fileshta/", - "https://www.bleepingcomputer.com/news/security/the-globe-ransomware-wants-to-purge-your-files/", - "https://decryptors.blogspot.co.il/2017/01/globe3-decrypter.html", - "https://decrypter.emsisoft.com/globe3" - ], - "synonyms": [ - "Purge Ransomware" - ] - }, - "related": [ - { - "dest-uuid": "5541471c-8d15-4aec-9996-e24b59c3e3d6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "fe16edbe-3050-4276-bac3-c7ff5fd4174a", - "value": "Globe3 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 500$ in bitcoins. Requires .NET Framework 4.0. Gets into your startup system and sends you notes like the one below: https://4.bp.blogspot.com/-xrr6aoB_giw/WG1UrGpmZJI/AAAAAAAAC-Q/KtKdQP6iLY4LHaHgudF5dKs6i1JHQOBmgCLcB/s1600/green1.jpg", - "meta": { - "date": "January 2017", - "encryption": "AES-256", - "extensions": [ - ".firecrypt" - ], - "payment-method": "Bitcoin", - "price": "500$", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-np8abNpYeoU/WG1KX4_H0yI/AAAAAAAAC98/gxRJeDb01So5yTboXYP7sZWurJFBbWziACLcB/s1600/note-html.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/bleedgreen-ransomware.html", - "https://www.bleepingcomputer.com/news/security/firecrypt-ransomware-comes-with-a-ddos-component/" - ], - "synonyms": [ - "FireCrypt Ransomware" - ] - }, - "uuid": "fbb3fbf9-50d7-4fe1-955a-fd4defa0cb08", - "value": "BleedGreen Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Original name is Mission 1996 or Mission: “Impossible” (1996) (like the movie)", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".BTC" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "BTC_DECRYPT_FILES.txt", - "BTC_DECRYPT_FILES.html" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-uiHluU553MU/WGzoFpEWkfI/AAAAAAAAC9o/M34ndwHUsoEfZiLJv9j4PCgBImS8oyYaACLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/btcamant.html" - ] - }, - "uuid": "a5826bd3-b457-4aa9-a2e7-f0044ad9992f", - "value": "BTCamant Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. It is also possible to break in using RDP Windows with the help of Pass-the-Hash system, PuTTY, mRemoteNG, TightVNC, Chrome Remote Desktop, modified version of TeamViewer, AnyDesk, AmmyyAdmin, LiteManager, Radmin and others. Ransom is 700$ in Bitcoins.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - "_x3m", - "_r9oj", - "_locked" - ], - "payment-method": "Bitcoin", - "price": "700$", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-hMAakgAORvg/WG_i-lk09II/AAAAAAAADAI/Uq2iCHC5ngYzeVcuxQF0mcbrLqyOGcA_wCLcB/s1600/note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/x3m-ransomware.html" - ] - }, - "uuid": "192bc3e8-ace8-4229-aa88-37034a11ef5b", - "value": "X3M Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".LOCKED" - ], - "payment-method": "Bitcoin - WebSite (onion)", - "ransomnotes-filenames": [ - "DecryptFile.txt" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-cAnilnXjK7k/WG_OHhC_UdI/AAAAAAAAC_4/sdbzTx9hP4sryM7xE59ONdk7Zr8D_m6XwCLcB/s1600/note-txt_2.png", - "https://1.bp.blogspot.com/-TDK91s7FmNM/WGpcwq5HmwI/AAAAAAAAC8Q/i0Q66vE7m-0kmrKPXWdwnYQg6Eaw2KSDwCLcB/s1600/note-pay_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/gog-ransomware.html", - "https://twitter.com/BleepinComputer/status/816112218815266816" - ] - }, - "uuid": "c3ef2acd-cc5d-4240-80e7-47e85b46db96", - "value": "GOG Ransomware" - }, - { - "description": "RegretLocker is a new ransomware that has been found in the wild in the last month that does not only encrypt normal files on disk like other ransomwares. When running, it will particularly search for VHD files, mount them using Windows Virtual Storage API, and then encrypt all the files it finds inside of those VHD files.", - "meta": { - "date": "November 2020", - "encryption": "AES", - "extensions": [ - ".mouse" - ], - "refs": [ - "http://chuongdong.com/reverse%20engineering/2020/11/17/RegretLocker/" - ] - }, - "uuid": "9479d372-605e-408e-a2a3-ea971ad4ad78", - "value": "RegretLocker" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 0.1 Bitcoins. Original name is TrojanRansom.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".edgel" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-dNBgohC1UYg/WGnXhem546I/AAAAAAAAC7w/Wv0Jy4173xsBJDZPLMxe6lXBgI5BkY4BgCLcB/s1600/note-lock.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/edgelocker-ransomware.html", - "https://twitter.com/BleepinComputer/status/815392891338194945" - ] - }, - "uuid": "ecfa106d-0aff-4f7e-a259-f00eb14fc245", - "value": "EdgeLocker" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Fake name: Microsoft Corporation. Based on HiddenTear", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Website", - "ransomnotes-filenames": [ - "MESSAGE.txt" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-tDS74fDwB1Q/WGk2D5DcUYI/AAAAAAAAC6s/vahju5JD9B4chwnNDUvDPp4ejZOxnj_awCLcB/s1600/note-wallp.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/red-alert-ransomware.html", - "https://twitter.com/JaromirHorejsi/status/815557601312329728" - ] - }, - "related": [ - { - "dest-uuid": "cd5f5165-7bd3-4430-b0bc-2c8fa518f618", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "f762860a-5e7a-43bf-bef4-06bd27e0b023", - "value": "Red Alert" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "1.5", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-T0PhVuoFSyA/WGk5mYkRFAI/AAAAAAAAC64/j14Pt84YUmQMNa_5LSEn6fZ5CoYqz60swCLcB/s1600/note-lock.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/first-ransomware.html" - ] - }, - "uuid": "ed26fcf3-47fb-45cc-b5f9-de18f6491934", - "value": "First" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Written on Delphi. The user requests the victim to get in touch with him through ICQ to get the ransom and return the files.", - "meta": { - "date": "January 2017", - "encryption": "Twofish", - "payment-method": "Email", - "ransomnotes-filenames": [ - "Xhelp.jpg" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-XZNMg5P75r4/WI985j-EKHI/AAAAAAAADcw/jGdtXoq2pnwjlAbFAJia4UsXuJrV5AU3gCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/xcrypt-ransomware.html", - "https://twitter.com/JakubKroustek/status/825790584971472902" - ], - "synonyns": [ - "XCrypt" - ] - }, - "uuid": "fd5bb71f-80dc-4a6d-ba8e-ed74999700d3", - "value": "XCrypt Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "January 2017", - "encryption": "Twofish", - "extensions": [ - ".7zipper" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-BR0DvtIft7g/WI95IF7IdUI/AAAAAAAADck/gzWAMbpFvaYicHFuMzvlM3YGJpgulMQBQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/7zipper-ransomware.html", - "https://1.bp.blogspot.com/-ClM0LCPjQuk/WI-BgHTpdNI/AAAAAAAADc8/JyEQ8-pcJmsXIntuP-MMdE-pohVncxTXQCLcB/s1600/7-zip-logo.png" - ] - }, - "uuid": "d8ec9e54-a4a4-451e-9f29-e7503174c16e", - "value": "7Zipper Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 170$ or EUR in Bitcoins.", - "meta": { - "date": "January 2017", - "encryption": "AES", - "extensions": [ - ".lock", - ".locked" - ], - "payment-method": "Bitcoin", - "price": "170€/$", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-SF4RsOANlI0/WJBQd4SJv6I/AAAAAAAADdY/hI-Ncw9FoFMi5jvljUftpzTgdykOfR3vgCLcB/s1600/lock-wallp_2.png.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/zyka-ransomware.html", - "https://www.pcrisk.com/removal-guides/10899-zyka-ransomware", - "https://download.bleepingcomputer.com/demonslay335/StupidDecrypter.zip", - "https://twitter.com/GrujaRS/status/826153382557712385" - ] - }, - "uuid": "7b7c8124-c679-4201-b5a5-5e66e6d52b70", - "value": "Zyka Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to strike worldwide. This ransomware does not really encrypt your files. Ransom requested is £50 using credit card.", - "meta": { - "date": "January 2017", - "encryption": "AES-256 (fake)", - "payment-method": "Bitcoin", - "price": "50£", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-zShnOIf3R_E/WJBfhC4CdSI/AAAAAAAADdo/6l4hwSOmI0Evj4W0Esj1S_uNOy5Yq6X0QCLcB/s1600/note1-2-3.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/sureransom-ransomware.html", - "http://www.forbes.com/sites/leemathews/2017/01/27/fake-ransomware-is-tricking-people-into-paying/#777faed0381c" - ] - }, - "uuid": "a9365b55-acd8-4b70-adac-c86d121b80b3", - "value": "SureRansom Ransomeware (Fake)" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. This ransomware uses the known online library as a decoy. It poses as Netflix Code generator for Netflix login, but instead encrypts your files. The ransom is 100$ in Bitcoins.", - "meta": { - "date": "January 2017", - "encryption": "AES-256", - "extensions": [ - ".se" - ], - "payment-method": "Bitcoin", - "price": "0.18 (100$)", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-vODt2aB9Hck/WJCFc3g5eCI/AAAAAAAADe8/OrEVkqUHMU4swRWedoZuBu50AWoKR1FGACLcB/s1600/netflix-note.jpg", - "https://4.bp.blogspot.com/-Cw4e1drBKl4/WJCHmgp1vtI/AAAAAAAADfI/QqFxUsuad" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2017/01/netflix-ransomware.html", - "http://blog.trendmicro.com/trendlabs-security-intelligence/netflix-scam-delivers-ransomware/", - "https://www.bleepingcomputer.com/news/security/rogue-netflix-app-spreads-netix-ransomware-that-targets-windows-7-and-10-users/", - "http://www.darkreading.com/attacks-breaches/netflix-scam-spreads-ransomware/d/d-id/1328012", - "https://4.bp.blogspot.com/-bQQ4DTIClvA/WJCIh6Uq2nI/AAAAAAAADfY/hB5HcjuGgh8rRJKeLHo__IRz3Ezth22-wCEw/s1600/form1.jpg", - "https://4.bp.blogspot.com/-ZnWdPDprJOg/WJCPeCtP4HI/AAAAAAAADfw/kR0ifI1naSwTAwSuOPiw8ZCPr0tSIz1CgCLcB/s1600/netflix-akk.png" - ] - }, - "uuid": "1317351f-ec8f-4c76-afab-334e1384d3d3", - "value": "Netflix Ransomware" - }, - { - "description": "It’s directed to English and Italian speaking users, therefore is able to infect worldwide. Most attacks are on organizations and servers. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. They pose as a Consumer complaint notification that’s coming from Federal Trade Commission from USA, with an attached file called “complaint.pdf”. Written in Delphi by hacker MicrRP.", - "meta": { - "date": " December 2016", - "encryption": "AES-256", - "extensions": [ - ".MRCR1", - ".PEGS1", - ".RARE1", - ".RMCM1", - ".MERRY" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "YOUR_FILES_ARE_DEAD.HTA", - "MERRY_I_LOVE_YOU_BRUCE.HTA" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-3F3QAZnDxsI/WGpvD4wZ2OI/AAAAAAAAC80/-2L6dIPqsgs8hZHOX0T6AFf5LwPwfZ-rwCLcB/s1600/note.png", - "https://4.bp.blogspot.com/-_w8peyLMcww/WHNJ1Gb0qeI/AAAAAAAADBw/EVbR-gKipYoNujo-YF6VavafsUfWDANEQCLcB/s1600/8-1-17.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/mrcr1-ransomware.html", - "https://www.bleepingcomputer.com/news/security/-merry-christmas-ransomware-now-steals-user-private-data-via-diamondfox-malware/", - "http://www.zdnet.com/article/not-such-a-merry-christmas-the-ransomware-that-also-steals-user-data/", - "https://www.bleepingcomputer.com/news/security/merry-christmas-ransomware-and-its-dev-comodosecurity-not-bringing-holiday-cheer/", - "https://decrypter.emsisoft.com/mrcr" - ], - "synonyms": [ - "Merry X-Mas", - "MRCR" - ] - }, - "uuid": "72cbed4e-b26a-46a1-82be-3d0154fdd2e5", - "value": "Merry Christmas" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Seoirse is how in Ireland people say the name George. Ransom is 0.5 Bitcoins.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".seoire" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/seoirse-ransomware.html" - ] - }, - "uuid": "bdf807c2-74ec-4802-9907-a89b1d910296", - "value": "Seoirse Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Every file is encrypted with a personal AES-key, and then AES-key encrypts with a RSA-1028 key. Hacking by TeleBots (Sandworm). Goes under a fake name: Update center or Microsoft Update center.", - "meta": { - "date": "November/December 2016", - "encryption": "AES-256+RSA", - "payment-method": "Bitcoin", - "price": "222 (200 000$)", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-8MqANWraAgE/WGT7mj-XirI/AAAAAAAAC3g/H_f1hTxa7Sc_DEtllBe-vYaAfY-YqMelgCLcB/s1600/wallp.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/killdisk-ransomware.html", - "https://www.bleepingcomputer.com/news/security/killdisk-ransomware-now-targets-linux-prevents-boot-up-has-faulty-encryption/", - "https://www.bleepingcomputer.com/news/security/killdisk-disk-wiping-malware-adds-ransomware-component/", - "http://www.zdnet.com/article/247000-killdisk-ransomware-demands-a-fortune-forgets-to-unlock-files/", - "http://www.securityweek.com/destructive-killdisk-malware-turns-ransomware", - "http://www.welivesecurity.com/2017/01/05/killdisk-now-targeting-linux-demands-250k-ransom-cant-decrypt/", - "https://cyberx-labs.com/en/blog/new-killdisk-malware-brings-ransomware-into-industrial-domain/" - ] - }, - "uuid": "8e067af6-d1f7-478a-8a8e-5154d2685bd1", - "value": "KillDisk Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Maker is arizonacode and ransom amount is 20-30$. If the victim decides to pay the ransom, he will have to copy HWID and then speak to the hacker on Skype and forward him the payment.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".deria" - ], - "payment-method": "Bitcoin", - "price": "20 - 30$", - "ransomnotes-filenames": [ - "unlock-everybody.txt" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-9vg_tRPq8rQ/WGOjf4ULuGI/AAAAAAAACzw/d16uRmEOotsCbRM4hwvzQ6bB8xAVNJ7ogCLcB/s1600/DeriaLock.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/derialock-ransomware.html", - "https://www.bleepingcomputer.com/news/security/new-derialock-ransomware-active-on-christmas-includes-an-unlock-all-command/" - ] - }, - "uuid": "c0d7acd4-5d64-4571-9b07-bd4bd0d27ee3", - "value": "DeriaLock Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".bript" - ], - "payment-method": "Email - Bitcoin", - "ransomnotes-filenames": [ - "More.html" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-hApL-ObdWsk/WGAYUyCzPcI/AAAAAAAACyg/NuL26zNgRGcLnnF2BwgOEn3AYMgVu3gQACLcB/s1600/More-note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/badencript-ransomware.html", - "https://twitter.com/demonslay335/status/813064189719805952" - ] - }, - "uuid": "43bfbb2a-9416-44da-81ef-03d6d3a3923f", - "value": "BadEncript Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The name of the creator is puff69.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".adam" - ], - "payment-method": "Website", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-9IgXt6L0hLY/WGARdzJgfvI/AAAAAAAACyQ/1bfnX_We65AirDcAFpiG49NPuBMfGH9wwCLcB/s1600/note-adam.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/adamlocker-ransomware.html" - ] - }, - "uuid": "5e7d10b7-18ec-47f7-8f13-6fd03d10a8bc", - "value": "AdamLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. This ransomware poses as Windows 10 Critical Update Service. Offers you to update your Windows 10, but instead encrypts your files. For successful attack, the victim must have .NET Framework 4.5.2 installed on him computer.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".alphabet" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-bFPI3O1BI3s/WGPpvnDvNNI/AAAAAAAAC10/mLUiFOCWnEkjbV91PmUGnc3qsFMv9um8QCLcB/s1600/wallp.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/alphabet-ransomware.html", - "https://twitter.com/PolarToffee/status/812331918633172992" - ] - }, - "related": [ - { - "dest-uuid": "5060756f-8385-465d-a7dd-7bf09a54da92", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "dd356ed3-42b8-4587-ae53-95f933517612", - "value": "Alphabet Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread by its creator in forums. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files and documents and more. The ransom is 0.1 bitcoins within 72 hours. Uses Windows Update as a decoy. Creator: Talnaci Alexandru", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".kokolocker" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-NiQ6rSIprB8/WF-uxTMq6hI/AAAAAAAACyA/tA6qO3aJdGc0Dn_I-IOZOM3IwN5rgq9sACLcB/s1600/note-koko.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/kokokrypt-ransomware.html", - "http://removevirusadware.com/tips-for-removeing-kokokrypt-ransomware/" - ], - "synonyms": [ - "KokoLocker Ransomware" - ] - }, - "uuid": "d672fe4f-4561-488e-bca6-20385b53d77f", - "value": "KoKoKrypt Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 0.5 bitcoins. The name of the creator is staffttt, he also created Fake CryptoLocker", - "meta": { - "date": "December 2016", - "encryption": "AES-256+RSA", - "extensions": [ - ".l33tAF" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "YOU_HAVE_BEEN_HACKED.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-yncl7-Jy198/WGDjdgNKXjI/AAAAAAAACzA/bfkDgwWEGKggUG3E1tgPBAWDXwi-p-7AwCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/l33taf-locker-ransomware.html" - ] - }, - "uuid": "791a6720-d589-4cf7-b164-08b35b453ac7", - "value": "L33TAF Locker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam (for example: “you have a criminal case against you”), fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "AES-256+RSA", - "payment-method": "Bitcoin", - "price": "0.6 - 1.6", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-T9Mt0pE7kwY/WF7NKAPfv1I/AAAAAAAACxw/gOjxeSR0x7EurKQTI2p6Ym70ViYuYdsvQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/pclock4-sysgop-ransomware.html" - ], - "synonyms": [ - "PClock SysGop Ransomware" - ] - }, - "uuid": "b78be3f4-e39b-41cc-adc0-5824f246959b", - "value": "PClock4 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. This ransomware uses VBS-script to send a voice message as the first few lines of the note.", - "meta": { - "date": "December 2016", - "encryption": "AES-256+RSA", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.4", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-0-kDVCM-kuI/WGVH-d2trGI/AAAAAAAAC4A/4LlxFpwkhEk89QcJ5ZhO1i-T6dQ_RcVegCEw/s1600/guster-note-2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/guster-ransomware.html", - "https://twitter.com/BleepinComputer/status/812131324979007492" - ] - }, - "uuid": "ffa7ac2f-b216-4fac-80be-e859a0e0251f", - "value": "Guster Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The hacker requests the ransom in Play Store cards. https://3.bp.blogspot.com/-ClUef8T55f4/WGKb8U4GeaI/AAAAAAAACzg/UFD0X2sORHYTVRNBSoqd5q7TBrOblQHmgCLcB/s1600/site.png", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".madebyadam" - ], - "payment-method": "Website (gift card)", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-ZIWywQMf2mY/WGJD-rqLZYI/AAAAAAAACzQ/p5PWlpWyHjcVHKq74DOsE7yS-ornW48_QCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/roga-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "175ebcc0-d74f-49b2-9226-c660ca1fe2e8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "cd1eb48e-070b-418e-8d83-4644a388f8ae", - "value": "Roga" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Creator is staffttt and the ransom is 0.5 botcoins.", - "meta": { - "date": "December 2016", - "encryption": "AES-128+RSA", - "extensions": [ - ".cryptolocker" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-LDSJ7rws1WI/WGDR-oDSshI/AAAAAAAACyw/_Kn0mnjpm2YN5tS9YldEnca-zOLJpXjcACLcB/s1600/crypto1-2.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/cryptolocker3-ransomware.html" - ], - "synonyms": [ - "Fake CryptoLocker" - ] - }, - "uuid": "4094b021-6654-49d5-9b80-a3666a1c1e44", - "value": "CryptoLocker3 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The ransom is 1.0 bitcoins.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".crypted" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-TkMikT4PA3o/WFrb4it2u9I/AAAAAAAACww/_zZgu9EHBj8Ibar8i5ekwaowGBD8EoOygCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/proposalcrypt-ransomware.html", - "http://www.archersecuritygroup.com/what-is-ransomware/", - "https://twitter.com/demonslay335/status/812002960083394560", - "https://twitter.com/malwrhunterteam/status/811613888705859586" - ] - }, - "uuid": "4cf270e7-e4df-49d5-979b-c13d8ce117cc", - "value": "ProposalCrypt Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The hacker demands 0.2 bitcoins. The ransomware poses as a Window update.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "0.2 (160$)", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-85wiBKXIqro/WFrFOaNeSsI/AAAAAAAACwA/UyrPc2bKQCcznmtLTFkEfc6lEvhseyRYACLcB/s1600/lock1.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/manifestus-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-23rd-2016-cryptxxx-koolova-cerber-and-more/", - "https://twitter.com/struppigel/status/811587154983981056" - ] - }, - "uuid": "e62ba8f5-e7ce-44ab-ac33-713ace192de3", - "value": "Manifestus Ransomware " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The name of the hacker is humanpuff69 and he requests 0.5 bitcoins. The encryption password is based on the computer name", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".fucked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-owEtII_eezA/WFmOp0ccjaI/AAAAAAAACvk/gjYcSeflS4AChm5cYO5c3EV4aSmzr14UwCLcB/s1600/enc100.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/enkripsipc-ransomware.html", - "https://twitter.com/demonslay335/status/811343914712100872", - "https://twitter.com/BleepinComputer/status/811264254481494016", - "https://twitter.com/struppigel/status/811587154983981056" - ], - "synonyms": [ - "IDRANSOMv3", - "Manifestus" - ] - }, - "related": [ - { - "dest-uuid": "5b75db42-b8f2-4e52-81d3-f329e49e1af2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "52caade6-ba7b-474e-b173-63f4332aa808", - "value": "EnkripsiPC Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. So far the victims are from Belarus and Germany.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".braincrypt" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-KrKO1vYs-1w/WFlw6bOfI_I/AAAAAAAACug/42w1VSl2GIoxRuA2SPKJr6xYp3c4OBnJQCLcB/s1600/note_2.png", - "https://3.bp.blogspot.com/-8bxTSAADM7M/WFmBEu-eUXI/AAAAAAAACvU/xaQBufV5a-4GWEJhXj2VVLqXnTjQJYNrwCLcB/s1600/note-brain2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/braincrypt-ransomware.html" - ] - }, - "uuid": "ade6ec5e-e082-43cb-9b82-ff8c0f4d7e56", - "value": "BrainCrypt Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Ransom is 0.2 bitcoins.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes-filenames": [ - "RESTORE_YOUR_FILES.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-R-lKbH_tLvs/WGPRa-hCtqI/AAAAAAAAC1Y/zgKYZmys_jciaYhtTUsVLen5IHX8_LyiACLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/msn-cryptolocker-ransomware.html", - "https://twitter.com/struppigel/status/810766686005719040" - ] - }, - "uuid": "7de27419-9874-4c3f-b75f-429a507ed7c5", - "value": "MSN CryptoLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The ransom is in the amount is 0.3 bitcoins. The ransomware is disguises themselves as Adobe Systems, Incorporated. RaaS", - "meta": { - "date": "December 2016", - "encryption": "RSA-2048", - "payment-method": "Bitcoin", - "price": "0.3", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-4Y7GZEsWh7A/WFfnmQFF7nI/AAAAAAAACsQ/j3rXZmWrDxMM6xhV1s4YVl_WLDe28cpAwCLcB/s1600/001.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/cryptoblock-ransomware.html", - "https://twitter.com/drProct0r/status/810500976415281154" - ] - }, - "uuid": "7b0df78e-8f00-468f-a6ef-3e1bda2a344c", - "value": "CryptoBlock Ransomware " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "AES-256 (ECB) + RSA-2048", - "extensions": [ - ".aes256" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "!!! READ THIS -IMPORTANT !!!.txt" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-GdF-kk1j9-8/WFl6NVm3PAI/AAAAAAAACvE/guFIi_FUpgIQNzX-usJ8CpofX45eXPvkQCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/aes-ni-ransomware.html" - ] - }, - "uuid": "69c9b45f-f226-485f-9033-fcb796c315cf", - "value": "AES-NI Ransomware " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The hacker of this ransomware tends to make lots of spelling errors in his requests. With Italian text that only targets the Test folder on the user's desktop", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "extensions": [ - ".encrypted" - ], - "payment-method": "Game", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-kz7PePfAiLI/WGTpY3us5LI/AAAAAAAAC3A/wu1rkx-BWlMzglJXXmCxeuYzbZKN5FP4gCLcB/s1600/koolova-v2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/koolova-ransomware.html", - "https://www.bleepingcomputer.com/news/security/koolova-ransomware-decrypts-for-free-if-you-read-two-articles-about-ransomware/" - ] - }, - "uuid": "ff6b8fc4-cfe0-45c1-9814-3261e39b4c9a", - "value": "Koolova Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… The ransom is 1bitcoin.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".crypt", - ".emilysupp" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "HOW_OPEN_FILES.hta" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-F8oAU82KnQ4/WFWgxjZz2vI/AAAAAAAACrI/J76wm21b5K4F9sjLF1VcEGoif3cS-Y-bwCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/fake-globe-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-30th-2016-infected-tvs-and-open-source-ransomware-sucks/", - "https://twitter.com/fwosar/status/812421183245287424", - "https://decrypter.emsisoft.com/globeimposter", - "https://twitter.com/malwrhunterteam/status/809795402421641216", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/", - "https://twitter.com/GrujaRS/status/1004661259906768896" - ], - "synonyms": [ - "Globe Imposter", - "GlobeImposter" - ] - }, - "related": [ - { - "dest-uuid": "73806c57-cef8-4f7b-a78b-7949ef83b2c2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "e03873ef-9e3d-4d07-85d8-e22a55f60c19", - "value": "Fake Globe Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc…", - "meta": { - "date": "December 2016", - "encryption": "RSA", - "extensions": [ - ".v8" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-Acmbpw6fEaQ/WFUFKU9V9ZI/AAAAAAAACqc/47AceoWZzOwP9qO8uenjNVOVXeFJf7DywCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/v8locker-ransomware.html" - ] - }, - "uuid": "45862a62-4cb3-4101-84db-8e338d17e283", - "value": "V8Locker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It SUPPOSEDLY encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc., however your files are not really encrypted, only the names are changed.", - "meta": { - "date": "December 2016", - "encryption": "RSA", - "extensions": [ - ".ENC" - ], - "payment-method": "Website", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-I0fsQu2YXMI/WFLb9LPdkFI/AAAAAAAACoY/xqRhgO1o98oruVDMC6rO4RxCk5MFDSTYgCLcB/s1600/lock.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/cryptorium-ransomware.html" - ] - }, - "uuid": "96bd63e5-99bd-490c-a23a-e0092337f6e6", - "value": "Cryptorium (Fake Ransomware)" - }, - { - "description": "It’s directed to Russian speaking users, there fore is able to infect mosty the old USSR countries. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc … The hacker goes by the nickname Antihacker and requests the victim to send him an email for the decryption. He does not request any money only a warning about looking at porn (gay, incest and rape porn to be specific).", - "meta": { - "date": "December 2016", - "encryption": "XOR", - "extensions": [ - ".antihacker2017" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-k7iDPgj17Zo/WFKEfMvR4wI/AAAAAAAACn4/8irB4Tf1x_MjfTmWaAjuae6mFJbva6GcwCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/antihacker2017-ransomware.html" - ] - }, - "uuid": "efd64e86-611a-4e10-91c7-e741cf0c58d9", - "value": "Antihacker2017 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect users all over the world. It is spread using email spam, fake updates, attachments and so on. It SUPPOSEDLY encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… Your files are not really encrypted and nothing actually happens, however the hacker does ask the victim to pay a sum of 100$, after 5 days the sum goes up to 250$ and thereafter to 500$. After the payment is received, the victim gets the following message informing him that he has been fooled and he simply needed to delete the note. https://4.bp.blogspot.com/-T8iSbbGOz84/WFGZEbuRfCI/AAAAAAAACm0/SO8Srwx2UIM3FPZcZl7W76oSDCsnq2vfgCPcB/s1600/code2.jpg", - "meta": { - "date": "December 2016", - "payment-method": "Dollars", - "price": "100 - 250 - 500", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-6I7jtsp5Wi4/WFLqnfUvg5I/AAAAAAAACow/BCOv7etYxxwpIERR1Qs5fmJ2wKBx3sqmACLcB/s1600/screen-locker.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/cia-special-agent-767-ransomware.html", - "https://www.bleepingcomputer.com/virus-removal/remove-cia-special-agent-767-screen-locker", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-16th-2016-samas-no-more-ransom-screen-lockers-and-more/", - "https://guides.yoosecurity.com/cia-special-agent-767-virus-locks-your-pc-screen-how-to-unlock/" - ] - }, - "uuid": "e479e32e-c884-4ea0-97d3-3c3356135719", - "value": "CIA Special Agent 767 Ransomware (FAKE!!!)" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… This hacker request your IP address in return for the decryption.", - "meta": { - "date": "December 2016", - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-LY1A0aeA_c0/WFEduvkiNQI/AAAAAAAACjk/B2-nFQoExscMVvZqvCaf9R4z_C6-rSdvACLcB/s1600/note2.png.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/loveserver-ransomware.html" - ] - }, - "uuid": "d1698a73-8be8-4c10-8114-8cfa1c399eb1", - "value": "LoveServer Ransomware " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… The hacker requests 2 bitcoins in return for the files.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".kraken", - "[base64].kraken" - ], - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes-filenames": [ - "_HELP_YOUR_FILES.html" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-E4brsgJRDHA/WFBU7wPaYLI/AAAAAAAACjU/sLEkzMiWp5wuc8hpFbylC7lLVMhftCLGgCLcB/s1600/111m.png", - "https://2.bp.blogspot.com/-b5caw8XAvIQ/WFBUuOto40I/AAAAAAAACjQ/_yzwIU17BHw4Ke4E3wM_XBI1XfnAvGSZQCLcB/s1600/005.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/kraken-ransomware.html" - ] - }, - "uuid": "51737c36-11a0-4c25-bd87-a990bd479aaf", - "value": "Kraken Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… The ransom is 0.25 bitcoins and the nickname of the hacker is FRC 2016.", - "meta": { - "date": "December 2016", - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "0.25", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-6iMtvGe3T58/WE8Ftx7zcUI/AAAAAAAACiE/2ISTxSYzgKEgnfQ7FSUWo3BiCeVLHH_uwCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/antix-ransomware.html" - ] - }, - "uuid": "8a7e0615-b9bd-41ab-89f1-62d041350e99", - "value": "Antix Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… The ransom is R$950 which is due in 5 days. (R$ is a Brazilian currency) Based off of Hidden-Tear", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "extensions": [ - ".sexy" - ], - "payment-method": "Bitcoin", - "price": "950 bresilian real ($)", - "ransomnotes-filenames": [ - "!!!!!ATENÇÃO!!!!!.html" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-MWEyG49z2Qk/WE78wLqCXPI/AAAAAAAAChw/SIlQSe_o_wMars2egfZ7VqKfWuan6ThwQCLcB/s1600/note1.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/payday-ransomware.html", - "https://twitter.com/BleepinComputer/status/808316635094380544" - ] - }, - "uuid": "70324b69-6076-4d00-884e-7f9d5537a65a", - "value": "PayDay Ransomware " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is NOT spread using email spam, fake updates, attachments and so on. It simply places a decrypt file on your computer.", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "extensions": [ - ".encrypted" - ], - "payment-method": "no ransom", - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/slimhem-ransomware.html" - ] - }, - "uuid": "76b14980-e53c-4209-925e-3ab024210734", - "value": "Slimhem Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… FILES DON’T REALLY GET DELETED NOR DO THEY GET ENCRYPTED!!!!!!!", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "payment-method": "Bitcoin", - "price": "0.3", - "ransomnotes": [ - "I want to play a game with you. Let me explain the rules. Your personal files are being deleted. Your photos, videos, documents, etc... But, don't worry! It will only happen if you don't comply. However I've already encrypted your personal files, so you cannot access therm. Every hour I select some of them to delete permanently, therefore I won't be able to access them, either. Are you familiar with the concept of exponential growth? Let me help you out. It starts out slowly then increases rapidly. During the first 24 hour you will only lose a few files, the second day a few hundred, the third day a few thousand, and so on. If you turn off your computer or try to close me, when i start the next time you will het 1000 files deleted as punishment. Yes you will want me to start next time, since I am the only one that is capable to decrypt your personal data for you. Now, let's start and enjoy our little game together! Send 0.3 bitcoins to this adress to unlock your Pc with your email adress Your can purchase bitcoins from localbitcoins" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-9MsC3A3tuUA/WFGZM45Pw5I/AAAAAAAACms/NbDFma30D9MpK2Zc0O6NvDizU8vqUWWlwCLcB/s1600/M4N1F3STO.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/m4n1f3sto-ransomware.html" - ] - }, - "uuid": "94a3be6b-3a83-40fb-85b2-555239260235", - "value": "M4N1F3STO Ransomware (FAKE!!!!!)" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… CHIP > DALE", - "meta": { - "date": "December 2016", - "encryption": "AES+RSA-512", - "extensions": [ - ".DALE" - ], - "payment-method": "Email", - "synonyms": [ - "DaleLocker Ransomware" - ] - }, - "uuid": "abe6cbe4-9031-46da-9e1c-89d9babe6449", - "value": "Dale Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… Based on the idiotic open-source ransomware called CryptoWire", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "extensions": [ - ".locked (added before the ending, not to the ending, for example: file.locked.doc" - ], - "payment-method": "Bitcoin", - "price": "1000 $", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-DOjKnuzCMo8/WE1Xd8yksiI/AAAAAAAACfo/d93v2xn857gQDg4o5Rd4oZpP3q-Ipv9xgCLcB/s1600/UltraLocker.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/ultralocker-ransomware.html", - "https://twitter.com/struppigel/status/807161652663742465" - ] - }, - "uuid": "3a66610b-5197-4af9-b662-d873afc81b2e", - "value": "UltraLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc…", - "meta": { - "date": "December 2016", - "encryption": "AES-256 and RSA-2048", - "extensions": [ - ".pre_alpha" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-6NIoKnSTwcs/WExcV900C_I/AAAAAAAACfI/_Hba3mOwk3UQ0T5rGercOglMsCTjVtCnQCLcB/s1600/note2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/aeskeygenassist-ransomware.html", - "https://id-ransomware.blogspot.co.il/2016/09/dxxd-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/634258/aes-key-gen-assistprotonmailcom-help-support/" - ] - }, - "uuid": "d755510f-d775-420c-83a0-b0fe9e483256", - "value": "AES_KEY_GEN_ASSIST Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "AES-256 and RSA-2048", - "extensions": [ - ".locky" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-Lyd1uRKG-94/WFJ3TbNqWfI/AAAAAAAACnc/4LoazYU0S1s1YRz3Xck3LN1vOm5RwIpugCLcB/s1600/note.jpg", - "https://4.bp.blogspot.com/-eBeh1lzEYsI/WFJ4l1oJ4fI/AAAAAAAACno/P5inceelNNk-zfkJGhE3XNamOGC8YmBwwCLcB/s1600/str123.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/code-virus-ransomware.html" - ] - }, - "uuid": "a23d7c45-7200-4074-9acf-8789600fa145", - "value": "Code Virus Ransomware " - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "December 2016", - "encryption": "Blowfish", - "extensions": [ - "_morf56@meta.ua_" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-Fh2I6542zi4/WEpmphY0i1I/AAAAAAAACe4/FBP3J6UraBMkSMTWx2tm-FRYnmlYLtFWgCLcB/s1600/note2.png.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/flkr-ransomware.html" - ] - }, - "uuid": "1cdc34ce-43b7-4df1-ae8f-ae0acbe5e4ad", - "value": "FLKR Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. These hackers claim to be students from Syria. This ransomware poses as the popular torrent movie screener called PopCorn. These criminals give you the chance to retrieve your files “for free” by spreading this virus to others. Like shown in the note bellow: https://www.bleepstatic.com/images/news/ransomware/p/Popcorn-time/refer-a-friend.png", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "extensions": [ - ".kok", - ".filock" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1", - "ransomnotes-filenames": [ - "restore_your_files.html", - "restore_your_files.txt" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-WxtRn5yVcNw/WEmgAPgO4AI/AAAAAAAACeo/M7iS6L8pSOEr8EUDkCK_g6h0aMKQQXfGwCLcB/s1600/note2.png", - "https://3.bp.blogspot.com/-sLwR-6y2M-I/WEmVIdJuPMI/AAAAAAAACeY/gpQDT-2-d7kkrfTHgiEZCfxViHu7dNE7ACLcB/s1600/med.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/popcorntime-ransomware.html", - "https://www.bleepingcomputer.com/news/security/new-scheme-spread-popcorn-time-ransomware-get-chance-of-free-decryption-key/" - ] - }, - "uuid": "c1b3477b-cd7f-4726-8744-a2c44275dffd", - "value": "PopCorn Time Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… NO POINT OF PAYING THE RANSOM—THE HACKER DOES NOT GIVE A DECRYPT AFTERWARDS.", - "meta": { - "date": "December 2016", - "encryption": "AES-256", - "extensions": [ - ".hacked" - ], - "payment-method": "Bitcoin", - "price": "0.33 - 0.5", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-G-xrI4N08hs/WFJjQgB3ojI/AAAAAAAACnM/DEfy_skSg044UmbBfNodiQY4OaLkkQPOwCLcB/s1600/note-hacked.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/hackedlocker-ransomware.html" - ] - }, - "uuid": "c2624d8e-da7b-4d94-b06f-363131ddb6ac", - "value": "HackedLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc…", - "meta": { - "date": "December 2016", - "encryption": "AES(CBC)", - "extensions": [ - "." - ], - "payment-method": "Bitcoin", - "price": "1.33 - 1.34", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-qcJxWivTx1w/WEcEW14om5I/AAAAAAAACa4/xLAlsQGZjeg7Zlg3F2fQAcgQ_6b_cNQLACLcB/s1600/goldeneye-1.jpg", - "https://4.bp.blogspot.com/-avE8liOWdPY/WEcEbdTxx6I/AAAAAAAACa8/KOKgXzU1h2EJ0tTOKMdQzZ_JdWWNeFMdwCLcB/s1600/goldeneye-1-2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/goldeneye-ransomware.html", - "https://www.bleepingcomputer.com/news/security/petya-ransomware-returns-with-goldeneye-version-continuing-james-bond-theme/", - "https://www.bleepingcomputer.com/forums/t/634778/golden-eye-virus/" - ] - }, - "related": [ - { - "dest-uuid": "7c5a1e93-7ab2-4b08-ada9-e82c4feaed0a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "ac7affb8-971d-4c05-84f0-172b61d007d7", - "value": "GoldenEye Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc…", - "meta": { - "date": "December 2016", - "encryption": "AES", - "extensions": [ - ".sage" - ], - "payment-method": "Bitcoin", - "price": "0.74 (545 $)", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-GasUzax8cco/WEar0U0tPqI/AAAAAAAACZw/6V_1JFxLMH0UnmLa3-WZa_ML9JbxF0JYACEw/s1600/note-txt2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/sage-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/634978/sage-file-sample-extension-sage/", - "https://www.bleepingcomputer.com/forums/t/634747/sage-20-ransomware-sage-support-help-topic/" - ] - }, - "uuid": "3e5a475f-7467-49ab-917a-4d1f590ad9b4", - "value": "Sage Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc… This hacker requests 4 bitcoins for ransom.", - "meta": { - "date": "December 2016", - "encryption": "AES and RSA-1024", - "extensions": [ - ".VO_" - ], - "payment-method": "Bitcoin", - "price": "4(1040 $)", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-Lhq40sgYUpI/WEWpGkkWOKI/AAAAAAAACZQ/iOp9g9Ya0Fk9vZrNKwTEMVcEOzKFIwqgACLcB/s1600/english-2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/12/sq-vo-ransomware.html" - ], - "synonyms": [ - "VO_ Ransomware" - ] - }, - "uuid": "5024f328-2595-4dbd-9007-218147e55d5f", - "value": "SQ_ Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc…", - "meta": { - "date": "December 2016", - "encryption": "AES and RSA", - "extensions": [ - ".MATRIX", - ".[Files4463@tuta.io]", - ".[RestorFile@tutanota.com]", - "[KOK8@protonmail.com].-.KOK8", - ".FOX", - ".EMAN50", - ".GMAN", - ".NOBAD", - ".ITLOCK" - ], - "payment-method": "Email", - "ransomnotes": [ - "WHAT HAPPENED WITH YOUR FILES?\nYour documents, databases, backups, network folders and other important files are encrypted with RSA-2048 and AES-128 ciphers.\nMore information about the RSA and AES can be found here:\nhttp://en.wikipedia.org/wiki/RSA_(cryptosystem)\nhttp://en.wikipedia.org/wiki/Advanced_Encryption_Standard\nIt mеаns thаt yоu will nоt bе аblе tо аccеss thеm аnуmоrе until thеу аrе dесrуptеd with yоur pеrsоnаl dесrуptiоn kеy! Withоut уоur pеrsоnаl kеy аnd sреciаl sоftwаrе dаtа rеcоvеrу is impоssiblе! If yоu will fоllоw оur instruсtiоns, wе guаrаntее thаt yоu cаn dесryрt аll yоur filеs quiсkly аnd sаfеly!\nIf yоu wаnt tо rеstоrе yоur filеs, plеаsе writе us tо thе е-mаils:\nFiles4463@tuta.io\nFiles4463@protonmail.ch\nFiles4463@gmail.com\nIn subjеct linе оf your mеssаgе writе yоur pеrsоnаl ID:\n4292D68970C047D9\nWе rесоmmеnd yоu tо sеnd yоur mеssаgе ОN ЕАСH оf ОUR 3 ЕМАILS, duе tо thе fасt thаt thе mеssаgе mау nоt rеаch thеir intеndеd rеcipiеnt fоr а vаriеtу оf rеаsоns!\nPlеаsе, writе us in Еnglish оr usе prоfеssiоnаl trаnslаtоr!\nIf yоu wаnt tо rеstоrе yоur filеs, yоu hаvе tо pаy fоr dесrуptiоn in Bitсоins. Thе pricе dереnds оn hоw fаst уоu writе tо us.\nYour message will be as confirmation you are ready to pay for decryption key. After the payment you will get the decryption tool with instructions that will decrypt all your files including network folders.\nTо cоnfirm thаt wе cаn dесryрt yоur filеs yоu cаn sеnd us up tо 3 filеs fоr frее dесrурtiоn. Plеаsе nоte thаt filеs fоr frее dесrурtiоn must NОT cоntаin аnу vаluаblе infоrmаtiоn аnd thеir tоtаl sizе must bе lеss thаn 5Mb.\nYоu hаvе tо rеspоnd аs sооn аs pоssiblе tо еnsurе thе rеstоrаtiоn оf yоur filеs, bеcаusе wе wоnt kееp yоur dеcrуptiоn kеys аt оur sеrvеr mоre thаn оne wееk in intеrеst оf оur sеcuritу.\nNоtе thаt аll thе аttеmpts оf dесryptiоn by yоursеlf оr using third pаrty tооls will rеsult оnly in irrеvосаble lоss оf yоur dаtа.\n\nIf yоu did nоt rеcеivе thе аnswеr frоm thе аfоrеcitеd еmаils fоr mоrе then 6 hours, рlеаsе сhеck SРАМ fоldеr!\nIf yоu did nоt rеcеivе thе аnswеr frоm thе аfоrеcitеd еmаils fоr mоrе then 12 hours, рlеаsе trу tо sеnd уоur mеssаgе with аnоthеr еmаil sеrviсе!\nIf yоu did nоt rеcеivе thе аnswеr frоm thе аfоrеcitеd еmаils fоr mоrе then 24 hours (еvеn if уоu hаvе prеviоuslу rесеivеd аnswеr frоm us), рlеаsе trу tо sеnd уоur mеssаgе with аnоthеr еmаil sеrviсе tо еасh оf оur 3 еmаils!\nАnd dоn't fоrgеt tо chеck SPАМ fоldеr!", - "HOW TO RECOVER YOUR FILES INSTRUCTION\nATENTION!!!\nWe are realy sorry to inform you that ALL YOUR FILES WERE ENCRYPTED \nby our automatic software. It became possible because of bad server security.\nATENTION!!!\nPlease don't worry, we can help you to RESTORE your server to original\nstate and decrypt all your files quickly and safely!\n\nINFORMATION!!!\nFiles are not broken!!!\nFiles were encrypted with AES-128+RSA-2048 crypto algorithms.\nThere is no way to decrypt your files without unique decryption key and special software. Your unique decryption key is securely stored on our server. For our safety, all information about your server and your decryption key will be automaticaly DELETED AFTER 7 DAYS! You will irrevocably lose all your data!\n* Please note that all the attempts to recover your files by yourself or using third party tools will result only in irrevocable loss of your data!\n* Please note that you can recover files only with your unique decryption key, which stored on our side. If you will use the help of third parties, you will only add a middleman.\n\nHOW TO RECOVER FILES???\nPlease write us to the e-mail (write on English or use professional translator):\nPabFox@protonmail.com \nFoxHelp@cock.li\nFoxHelp@tutanota.com\nYou have to send your message on each of our 3 emails due to the fact that the message may not reach their intended recipient for a variety of reasons!\n\nIn subject line write your personal ID:\n[id]\nWe recommed you to attach 3 encrypted files to your message. We will demonstrate that we can recover your files. \n* Please note that files must not contain any valuable information and their total size must be less than 5Mb. \n\nOUR ADVICE!!!\nPlease be sure that we will find common languge. We will restore all the data and give you recommedations how to configure the protection of your server.\n\nWe will definitely reach an agreement ;) !!!" - ], - "ransomnotes-filenames": [ - "[5 numbers]-MATRIX-README.RTF", - "!ReadMe_To_Decrypt_Files!.rtf", - "#Decrypt_Files_ReadMe#.rtf", - "#KOK8_README#.rtf", - "#FOX_README#.rtf", - "!README_GMAN!.rtf", - "#README_EMAN50#.rtf", - "#NOBAD_README#.rtf", - "!ITLOCK_README!.rtf" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-RGHgroHt5cU/WEUWnFBn2hI/AAAAAAAACYA/zwSf7rmfWdo4ESQ8kjwj6mJrfzL2V22mgCLcB/s1600/note-eng.png", - "https://www.bleepstatic.com/images/news/ransomware/m/matrix/4-7-2018/1/ransom-note.jpg", - "https://www.bleepstatic.com/images/news/ransomware/m/matrix/4-7-2018/1/background.jpg", - "https://www.bleepstatic.com/images/news/ransomware/m/matrix/4-7-2018/2/wallpaper.jpg", - "https://pbs.twimg.com/media/DZ4VCRpWsAYtckw.jpg", - "https://pbs.twimg.com/media/DZ4V8uXWsAI0r1v.jpg", - "https://pbs.twimg.com/media/Do_pn7bX0AYh1F-.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-2nd-2016-screenlockers-kangaroo-the-sfmta-and-more/", - "https://id-ransomware.blogspot.co.il/2016/12/matrix-ransomware.html", - "https://twitter.com/rommeljoven17/status/804251901529231360", - "https://www.bleepingcomputer.com/news/security/new-matrix-ransomware-variants-installed-via-hacked-remote-desktop-services/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/", - "https://twitter.com/demonslay335/status/1034212374805278720", - "https://www.bleepingcomputer.com/news/security/new-fox-ransomware-matrix-variant-tries-its-best-to-close-all-file-handles/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/", - "https://twitter.com/demonslay335/status/1049314118409306112", - "https://twitter.com/demonslay335/status/1050118985210048512", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-september-14th-2018-kraken-dharma-and-matrix/", - "https://twitter.com/demonslay335/status/1039907030570598400" - ], - "synonyms": [ - "Malta Ransomware", - "Matrix Ransomware" - ] - }, - "uuid": "42ee85b9-45f8-47a3-9bab-b695ac271544", - "value": "Matrix" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-anaLWyg_iJI/WFaxDs8KI3I/AAAAAAAACro/yGXh3AV-ZpAKmD4fpQbBkAyYXXnkqgR3ACLcB/s1600/note666_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/satan666-ransomware.html" - ] - }, - "uuid": "03d92e7b-95ae-4c5b-8b58-daa2fd98f7a1", - "value": "Satan666 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on HiddenTear", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".R.i.P" - ], - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes-filenames": [ - "Important!.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-D-j_9_LZen0/WEPq4G5w5FI/AAAAAAAACXs/GTnckI3CGYQxuDMPXBzpGXDtarPK8yJ5wCLcB/s1600/note_2.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/rip-ransomware.html", - "https://twitter.com/BleepinComputer/status/804810315456200704" - ], - "synonyms": [ - "RIP", - "Phoenix" - ] - }, - "uuid": "5705df4a-42b0-4579-ad9f-8bfa42bae471", - "value": "RIP (Phoenix) Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on RemindMe", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".novalid" - ], - "payment-method": "Bitcoin - Link WebSite", - "ransomnotes-filenames": [ - "RESTORE_CORUPTED_FILES.HTML" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-BK_31ORE0ZY/WD284cEVoLI/AAAAAAAACWA/bU0n3MBMD8Mbgzv9bD6VLJb51Q_kr5AJgCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/novalid-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/634754/locked-in-ransomware-help-support-restore-corupted-fileshtml/", - "https://twitter.com/struppigel/status/807169774098796544" - ], - "synonyms": [ - "Locked-In Ransomware", - "NoValid Ransomware" - ] - }, - "uuid": "777f0b78-e778-435f-b4d5-e40f0b7f54c3", - "value": "Locked-In Ransomware or NoValid Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/chartwig-ransomware.html" - ] - }, - "uuid": "37fff5f8-8e66-43d3-a075-3619b6f2163d", - "value": "Chartwig Ransomware" - }, - { - "description": "It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The files don’t actually get encrypted, their names get changed using this formula: [www-hash-part-]+[number]+[.crypter]", - "meta": { - "date": "November 2016", - "encryption": "Rename > Ren + Locker", - "extensions": [ - ".crypter" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-281TI8xvMLo/WDw2Nl72OsI/AAAAAAAACTk/nT_rL0z-Exo93FzoOXnyaFgQ7wPe0r7IgCLcB/s1600/Crypter1.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/renlocker-ransomware.html" - ] - }, - "uuid": "957850f7-081a-4191-9e5e-cf9ff27584ac", - "value": "RenLocker Ransomware (FAKE)" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "payment-method": "Email", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-2dC_gQTed4o/WDxRSh_R-MI/AAAAAAAACT4/yWxzCcMqN_8GLjd8dOPf6Mw16mkbfALawCLcB/s1600/lblMain.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/thanksgiving-ransomware.html", - "https://id-ransomware.blogspot.co.il/2016/07/stampado-ransomware-1.html", - "https://twitter.com/BleepinComputer/status/801486420368093184" - ] - }, - "uuid": "459ea908-e39e-4274-8866-362281e24911", - "value": "Thanksgiving Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "RSA", - "extensions": [ - ".hannah" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/--45C2Cr8sXc/WDiWLTvW-ZI/AAAAAAAACSA/JnJNRr8Kti0YqSnfhPQBF2rsFf-au1g9ACLcB/s1600/Cockblocke.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/cockblocker-ransomware.html", - "https://twitter.com/jiriatvirlab/status/801910919739674624" - ] - }, - "uuid": "3a40c5ae-b117-45cd-b674-a7750e3f3082", - "value": "CockBlocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on the idiotic open-source ransomware called CryptoWire", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "0.68096697 (500$)", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-nXv88GxxOvQ/WE1gqeD3ViI/AAAAAAAACf4/wcVwQ9Pi_JEP2iWNHoBGmeXKJFsfwmwtwCLcB/s1600/Lomix.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/lomix-ransomware.html", - "https://twitter.com/siri_urz/status/801815087082274816" - ] - }, - "uuid": "e721b7c5-df07-4e26-b375-fc09a4911451", - "value": "Lomix Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. https://3.bp.blogspot.com/--jubfYRaRmw/WDaOyZXkAaI/AAAAAAAACQE/E63a4FnaOfACZ07s1xUiv_haxy8cp5YCACLcB/s1600/ozoza2.png", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".locked", - ".Locked" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "HOW TO DECRYPT YOU FILES.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-r-vBnl-wLwo/WDg7fHph9BI/AAAAAAAACRc/VuMxWa1nUPIGHCzhCf2AyL_uc7Z9iB6MACLcB/s1600/note_2.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/ozozalocker-ransomware.html", - "https://decrypter.emsisoft.com/ozozalocker", - "https://twitter.com/malwrhunterteam/status/801503401867673603" - ] - }, - "uuid": "d20b0d12-1a56-4339-b02b-eb3803dc3e6e", - "value": "OzozaLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".mo0n" - ], - "payment-method": "WebSite link", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-8-8X7Nd1MYs/WDSZN6NIT1I/AAAAAAAACNg/ltc7ppfZZL0vWn8BV3Mk9BVrdmJbcEnpgCLcB/s1600/222.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/crypute-ransomware-m0on.html", - "https://www.bleepingcomputer.com/virus-removal/threat/ransomware/" - ], - "synonyms": [ - "m0on Ransomware" - ] - }, - "uuid": "5539c8e7-2058-4757-b9e3-71ff7d41db31", - "value": "Crypute Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256 + RSA", - "extensions": [ - ".maktub" - ], - "payment-method": "Bitcoin", - "price": "0,5 - 1,5", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-_i9AjhlvjB8/WDVuLKBnmlI/AAAAAAAACOA/xISXMTBLMbEH4PBS35DQ416woPpkuiVvQCLcB/s1600/note-2.PNG", - "https://2.bp.blogspot.com/-4HNc9S8SY4I/WBMkpdKyDsI/AAAAAAAAB0I/udESgro7YB4pF98Dv2KrrecyymFGsvV2QCLcB/s1600/note.JPG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/nmoreira-ransomware.html", - "https://id-ransomware.blogspot.co.il/2016/10/airacrop-ransomware.html" - ], - "synonyms": [ - "Fake Maktub Ransomware" - ] - }, - "uuid": "9490641f-6a51-419c-b3dc-c6fa2bab4ab3", - "value": "NMoreira Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. The ransom amount is 349.99$ and the hacker seems to be from India. He disguises himself as Microsoft Support.", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".vindows" - ], - "payment-method": "Call Number", - "price": "349.99$", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-61DcGSFljUk/WDM2UpFZ02I/AAAAAAAACMw/smvauQCvG3IPHOtEjPP4ocGKmBhVRBv-wCLcB/s1600/lock-note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/vindowslocker-ransomware.html", - "https://malwarebytes.app.box.com/s/gdu18hr17mwqszj3hjw5m3sw84k8hlph", - "https://rol.im/VindowsUnlocker.zip", - "https://twitter.com/JakubKroustek/status/800729944112427008", - "https://www.bleepingcomputer.com/news/security/vindowslocker-ransomware-mimics-tech-support-scam-not-the-other-way-around/" - ] - }, - "uuid": "b58e1265-2855-4c8a-ac34-bb1504086084", - "value": "VindowsLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Here is the original ransomware under this name: http://id-ransomware.blogspot.co.il/2016/09/donald-trump-ransomware.html", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".ENCRYPTED" - ], - "payment-method": "no ransom", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-RwJ6R-uvYg0/V-qfeRPz7GI/AAAAAAAABi8/7x4MxRP7Jp8edbTJqz4iuEye0q1u5k3pQCLcB/s1600/donald-trump-ransomware.jpg", - "https://www.bleepingcomputer.com/news/security/the-donald-trump-ransomware-tries-to-build-walls-around-your-files/" - ], - "refs": [ - "http://id-ransomware.blogspot.co.il/2016/09/donald-trump-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-donald-trump-ransomware-tries-to-build-walls-around-your-files/" - ] - }, - "uuid": "96c10791-258f-4b2b-a2cc-b5abddbdb285", - "value": "Donald Trump 2 Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. Looks for C:\\Temp\\voldemort.horcrux", - "meta": { - "date": "November 2016", - "encryption": "RSA", - "payment-method": "CreditCard", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-qJHhbtoL1Y4/V-lOClxieEI/AAAAAAAABis/IbnVAY8hnmEfU8_iU1CgQ3FWeX4YZOkBACLcB/s1600/Nagini.jpg" - ], - "refs": [ - "http://id-ransomware.blogspot.co.il/2016/09/nagini-voldemort-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-nagini-ransomware-sics-voldemort-on-your-files/" - ], - "synonyms": [ - "Voldemort Ransomware" - ] - }, - "uuid": "46a35af7-9d05-4de4-a955-41ccf3d3b83b", - "value": "Nagini Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".l0cked", - ".L0cker" - ], - "payment-method": "Bitcoin", - "price": "100$", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-0N1ZUh4WcxQ/WDCfENY1eyI/AAAAAAAACKE/_RVIxRCwedMrD0Tj9o6-ew8u3pL0Y5w8QCLcB/s1600/lock-note2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/shelllocker-ransomware.html", - "https://twitter.com/JakubKroustek/status/799388289337671680" - ] - }, - "uuid": "a8ea7a67-c019-4c6c-8061-8614c47f153e", - "value": "ShellLocker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES + RSA-512", - "extensions": [ - ".CHIP", - ".DALE" - ], - "payment-method": "Tor WebSite", - "ransomnotes-filenames": [ - "CHIP_FILES.txt" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-OvB9TMJoimE/WC9QXRPFNwI/AAAAAAAACJU/iYcCC9tKvGIu4jH2bd6xLvmO7KMVVCLdgCLcB/s1600/note_2.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/chip-ransomware.html", - "http://malware-traffic-analysis.net/2016/11/17/index.html", - "https://www.bleepingcomputer.com/news/security/rig-e-exploit-kit-now-distributing-new-chip-ransomware/" - ], - "synonyms": [ - "ChipLocker Ransomware" - ] - }, - "uuid": "7487fd37-d4ba-4c85-b6f8-8d4d7d5b74d7", - "value": "Chip Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. CrySiS > Dharma Note: ATTENTION! At the moment, your system is not protected. We can fix it and restore files. To restore the system write to this address: bitcoin143@india.com. CrySiS variant", - "meta": { - "date": "November 2016", - "encryption": "AES + RSA-512", - "extensions": [ - ".dharma", - ".wallet", - ".zzzzz", - ".cmb", - ".id-BCBEF350.[paymentbtc@firemail.cc].cmb", - ".bip", - ".id-BCBEF350.[Beamsell@qq.com].bip", - ".boost", - ".[Darknes@420blaze.it].waifu", - ".brrr", - ".adobe", - ".tron", - ".AUDIT", - ".cccmn", - ".fire", - ".myjob", - ".[cyberwars@qq.com].war", - ".risk", - ".RISK", - ".bkpx", - ".[newsantaclaus@aol.com].santa" - ], - "payment-method": "Bitcoin - Email", - "ransomnotes": [ - "all your data has been locked us\nYou want to return?\nwrite email paymentbtc@firemail.cc", - "All your files have been encrypted!\nAll your files have been encrypted due to a security problem with your PC. If you want to restore them, write us to the e-mail paymentbtc@firemail.cc\nWrite this ID in the title of your message ACBFF130\nIn case of no answer in 24 hours write us to theese e-mails:paymentbtc@firemail.cc\nYou have to pay for decryption in Bitcoins. The price depends on how fast you write to us. After payment we will send you the decryption tool that will decrypt all your files.\nFree decryption as guarantee\nBefore paying you can send us up to 1 file for free decryption. The total size of files must be less than 1Mb (non archived), and files should not contain valuable information. (databases,backups, large excel sheets, etc.)\nHow to obtain Bitcoins\nThe easiest way to buy bitcoins is LocalBitcoins site. You have to register, click 'Buy bitcoins', and select the seller by payment method and price.\nhttps://localbitcoins.com/buy_bitcoins\nAlso you can find other places to buy Bitcoins and beginners guide here:\nhttp://www.coindesk.com/information/how-can-i-buy-bitcoins/\nAttention!\nDo not rename encrypted files.\nDo not try to decrypt your data using third party software, it may cause permanent data loss.\nDecryption of your files with the help of third parties may cause increased price (they add their fee to our) or you can become a victim of a scam.", - "All your files have been encrypted!\nAll your files have been encrypted due to a security problem with your PC. If you want to restore them, write us to the e-mail Beamsell@qq.com\nWrite this ID in the title of your message BCBEF350\nIn case of no answer in 24 hours write us to theese e-mails:Beamsell@qq.com\nYou have to pay for decryption in Bitcoins. The price depends on how fast you write to us. After payment we will send you the decryption tool that will decrypt all your files. \nFree decryption as guarantee\nBefore paying you can send us up to 1 file for free decryption. The total size of files must be less than 1Mb (non archived), and files should not contain valuable information. (databases,backups, large excel sheets, etc.) \nHow to obtain Bitcoins\nThe easiest way to buy bitcoins is LocalBitcoins site. You have to register, click 'Buy bitcoins', and select the seller by payment method and price. \nhttps://localbitcoins.com/buy_bitcoins \nAlso you can find other places to buy Bitcoins and beginners guide here: \nhttp://www.coindesk.com/information/how-can-i-buy-bitcoins/ \nAttention!\nDo not rename encrypted files. \nDo not try to decrypt your data using third party software, it may cause permanent data loss.\nDecryption of your files with the help of third parties may cause increased price (they add their fee to our) or you can become a victim of a scam.", - "all your data has been locked us\nYou want to return?\nwrite email Beamsell@qq.com" - ], - "ransomnotes-filenames": [ - "README.txt", - "README.jpg", - "Info.hta", - "FILES ENCRYPTED.txt", - "INFO.hta" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/d/dharma/cmb/hta-ransom-note.jpg", - "https://pbs.twimg.com/media/Dmof_FiXsAAAvTN.jpg", - "https://pbs.twimg.com/media/Dmof_FyXsAEJmgQ.jpg", - "https://pbs.twimg.com/media/DrWqLWzXgAc4SlG.jpg", - "https://pbs.twimg.com/media/DuEBIMBW0AANnGW.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/dharma-ransomware.html", - "https://www.bleepingcomputer.com/news/security/kaspersky-releases-decryptor-for-the-dharma-ransomware/", - "https://www.bleepingcomputer.com/news/security/new-cmb-dharma-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/new-bip-dharma-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/", - "https://twitter.com/demonslay335/status/1049313390097813504", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-september-14th-2018-kraken-dharma-and-matrix/", - "https://twitter.com/JakubKroustek/status/1038680437508501504", - "https://twitter.com/demonslay335/status/1059521042383814657", - "https://twitter.com/demonslay335/status/1059940414147489792", - "https://twitter.com/JakubKroustek/status/1060825783197933568", - "https://twitter.com/JakubKroustek/status/1064061275863425025", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-23rd-2018-stop-dharma-and-more/", - "https://www.youtube.com/watch?v=qjoYtwLx2TI", - "https://twitter.com/GrujaRS/status/1072139616910757888" - ] - }, - "uuid": "2b365b2c-4a9a-4b66-804d-3b2d2814fe7b", - "value": "Dharma Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".angelamerkel" - ], - "payment-method": "Bitcoin", - "price": "1200€", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-QaJ-Z27tL7s/WDCvwYY2UVI/AAAAAAAACKg/swpf1eKf1Y8oYIK5U8gbfi1H9AQ3Q3r8QCLcB/s1600/angela-merkel.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/angela-merkel-ransomware.html", - "https://twitter.com/malwrhunterteam/status/798268218364358656" - ] - }, - "uuid": "a9bb4ae1-b4da-49bb-aeeb-3596cb883860", - "value": "Angela Merkel Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - "._luck" - ], - "payment-method": "Bitcoin", - "price": "0.7 - 2.1", - "ransomnotes": [ - "%AppData%\\@WARNING_FILES_ARE_ENCRYPTED.[victim_id].txt." - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-skwh_-RY50s/WDK2XLhtt3I/AAAAAAAACL0/CaZ0A_fl2Zk-YZYU9g4QCQZkODpicbXpQCLcB/s1600/note_2.PNG", - "https://4.bp.blogspot.com/-tCYSY5fpE5Q/WDLLZssImkI/AAAAAAAACMg/7TmWPW3k4jQuGIYZN_dCxcSGcY_c4po9wCLcB/s1600/note3_2.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/cryptoluck-ransomware.html", - "http://www.bleepingcomputer.com/news/security/cryptoluck-ransomware-being-malvertised-via-rig-e-exploit-kits/", - "https://twitter.com/malwareforme/status/798258032115322880" - ], - "synonyms": [ - "YafunnLocker" - ] - }, - "uuid": "615b682d-4746-464d-8091-8869d0e6ea2c", - "value": "CryptoLuck Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256 + RSA + SHA-256", - "extensions": [ - "_crypt", - ".id-_locked", - ".id-_locked_by_krec", - ".id-_locked_by_perfect", - ".id-_x3m", - ".id-_r9oj", - ".id-_garryweber@protonmail.ch", - ".id-_steaveiwalker@india.com_", - ".id-_julia.crown@india.com_", - ".id-_tom.cruz@india.com_", - ".id-_CarlosBoltehero@india.com_", - ".id-_maria.lopez1@india.com_" - ], - "payment-method": "Bitcoin", - "price": "0.2 - 2", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-2fAMkigwn4E/WCs1vKiB9UI/AAAAAAAACIs/_kgk8U9wfisV0MTYInIbArwL8zgLyBDIgCLcB/s1600/note-eng.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/crypton-ransomware.html", - "https://decrypter.emsisoft.com/crypton", - "https://www.bleepingcomputer.com/news/security/crypton-ransomware-is-here-and-its-not-so-bad-/", - "https://twitter.com/JakubKroustek/status/829353444632825856" - ], - "synonyms": [ - "Nemesis", - "X3M" - ] - }, - "uuid": "117693d2-1551-486e-93e5-981945eecabd", - "value": "Crypton Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. pretends to be a Windows optimization program called Windows-TuneUp", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".karma" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "# DECRYPT MY FILES #.html", - "# DECRYPT MY FILES #.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/k/karma-ransomware/ransom-note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/karma-ransomware.html", - "https://www.bleepingcomputer.com/news/security/researcher-finds-the-karma-ransomware-being-distributed-via-pay-per-install-network/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-18th-2016-crysis-cryptoluck-chip-and-more/" - ] - }, - "uuid": "51596eaa-6df7-4aa3-8df4-cec3aeffb1b5", - "value": "Karma Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-CTLT300bjNk/WCg9mrJArSI/AAAAAAAACGk/weWSqTMVS9AXdxJh_SA06SOH4kh2VGW1gCLcB/s1600/note_2.PNG.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/wickedlocker-ht-ransomware.html" - ] - }, - "uuid": "878c06be-95d7-4a0d-9dba-178ffc1d3e5e", - "value": "WickedLocker HT Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. CryptoLocker Copycat", - "meta": { - "date": "November 2016", - "encryption": "AES or XOR", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.55 - 0.65", - "ransomnotes-filenames": [ - "Your files are locked !.txt", - "Your files are locked !!.txt", - "Your files are locked !!!.txt", - "Your files are locked !!!!.txt", - "%AppData%\\WinCL\\winclwp.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/old-cryptolocker-copycat-named-pclock-resurfaces-with-new-attacks/", - "https://id-ransomware.blogspot.co.il/2016/11/suppteam-ransomware-sysras.html", - "http://researchcenter.paloaltonetworks.com/2015/09/updated-pclock-ransomware-still-comes-up-short/", - "https://decrypter.emsisoft.com/" - ], - "synonyms": [ - "PClock SuppTeam Ransomware", - "WinPlock", - "CryptoLocker clone" - ] - }, - "uuid": "6c38f175-b32a-40ef-8cad-33c2c8840d51", - "value": "PClock3 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "XOR and RSA", - "extensions": [ - ".kolobocheg@aol.com_" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://www.ransomware.wiki/tag/kolobo/" - ], - "refs": [ - "https://www.ransomware.wiki/tag/kolobo/", - "https://id-ransomware.blogspot.co.il/2016/11/kolobo-ransomware.html", - "https://forum.drweb.com/index.php?showtopic=315142" - ], - "synonyms": [ - "Kolobocheg Ransomware" - ] - }, - "uuid": "f32f0bec-961b-4c01-9cc1-9cf409efd598", - "value": "Kolobo Ransomware" - }, - { - "description": "This is most likely to affect German speaking users, since the note is written in German. Mostly affects users in German speaking countries. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".cry_" - ], - "payment-method": "PaySafeCard", - "price": "100€", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-r2kaNLjBcEk/WCNCqrpHPZI/AAAAAAAACEE/eFSWuu4mUZoDV5AnduGR4KxHlFM--uIzACLcB/s1600/lock-screen.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/paysafegen-german-ransomware.html", - "https://twitter.com/JakubKroustek/status/796083768155078656" - ], - "synonyms": [ - "Paysafecard Generator 2016", - "PaySafeCard", - "PaySafeGen" - ] - }, - "uuid": "379d5258-6f11-4c41-a685-c2ff555c0cb9", - "value": "PaySafeGen (German) Ransomware" - }, - { - "description": "This is most likely to affect Russian speaking users, since the note is written in Russian. Therefore, residents of Russian speaking country are affected. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. The ransomware’s authors would request around $75 from their victims to provide them with a decryptor (payments are accepted via Russian payment services Qiwi or Yandex.Money ). Right from the start, however, researchers suggested that TeleCrypt was written by cybercriminals without advanced skills. Telecrypt will generate a random string to encrypt with that is between 10-20 length and only contain the letters vo,pr,bm,xu,zt,dq.", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".Xcri" - ], - "payment-method": "Qhvi-wallet / Yandex-wallet", - "price": "5000 rubles", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-UFksnOoE4Ss/WCRUNbQuqyI/AAAAAAAACFI/Gs3Gkby335UmiddlYWJDkw8O-BBLt-BlQCLcB/s1600/telegram_rans.gif" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/telecrypt-ransomware.html", - "http://www.securityweek.com/telecrypt-ransomwares-encryption-cracked", - "https://malwarebytes.app.box.com/s/kkxwgzbpwe7oh59xqfwcz97uk0q05kp3", - "https://blog.malwarebytes.com/threat-analysis/2016/11/telecrypt-the-ransomware-abusing-telegram-api-defeated/", - "https://securelist.com/blog/research/76558/the-first-cryptor-to-exploit-telegram/" - ] - }, - "uuid": "2f362760-925b-4948-aae5-dd0d2fc21002", - "value": "Telecrypt Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".cerber" - ], - "payment-method": "Bitcoin", - "price": "0.4", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-ftA6aPEXwPM/WCDY3IiSq6I/AAAAAAAACCU/lnH25navXDkNccw5eQL9fkztRAeIqDYdQCLcB/s1600/note111.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/cerbertear-ransomware.html", - "https://www.tripwire.com/state-of-security/security-data-protection/cyber-security/november-2016-month-ransomware/", - "https://twitter.com/struppigel/status/795630452128227333" - ] - }, - "uuid": "28808e63-e71f-4aaa-b203-9310745f87b6", - "value": "CerberTear Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Hidden Tear >> APT Ransomware + HYPERLINK \"https://id-ransomware.blogspot.ru/2016/05/remindme-ransomware-2.html\" \t \"_blank\" RemindMe > FuckSociety", - "meta": { - "date": "November 2016", - "encryption": "RSA-4096", - "extensions": [ - ".dll" - ], - "payment-method": "Bitcoin", - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/fucksociety-ransomware.html" - ] - }, - "uuid": "81c476c3-3190-440d-be4a-ea875e9415aa", - "value": "FuckSociety Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Batch file; Passcode: AES1014DW256 or RSA1014DJW2048", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".dng", - ".serpent" - ], - "payment-method": "Bitcoin", - "price": "0.33", - "ransomnotes-filenames": [ - "HOW_TO_DECRYPT_YOUR_FILES_[random_3_chars].html", - "HOW_TO_DECRYPT_YOUR_FILES_[random_3_chars].txt" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/paydos-ransomware-serpent.html", - "https://www.bleepingcomputer.com/news/security/ransomware-goes-retro-with-paydos-and-serpent-written-as-batch-files/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-4th-2016-cerber-paydos-alcatraz-locker-and-more/", - "https://www.proofpoint.com/us/threat-insight/post/new-serpent-ransomware-targets-danish-speakers" - ], - "synonyms": [ - "Serpent Ransomware" - ] - }, - "uuid": "4818a48a-dfc2-4f35-a76d-e4fb462d6c94", - "value": "PayDOS Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".dng" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/zscreenlocker-ransomware.html", - "https://www.tripwire.com/state-of-security/security-data-protection/cyber-security/november-2016-month-ransomware/", - "https://twitter.com/struppigel/status/794077145349967872" - ] - }, - "uuid": "47834caa-2226-4a3a-a228-210a64c281b9", - "value": "zScreenLocker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".rnsmwr" - ], - "payment-method": "Bitcoin", - "price": "0.03", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/11-4-16/CwZubUHW8AAE4qi[1].jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/gremit-ransomware.html", - "https://twitter.com/struppigel/status/794444032286060544", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-4th-2016-cerber-paydos-alcatraz-locker-and-more/" - ] - }, - "uuid": "47512afc-ecf2-4766-8487-8f3bc8dddbf3", - "value": "Gremit Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".hollycrypt" - ], - "payment-method": "Bitcoin Email", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-PdtXGwSTn24/WBxIoomzF4I/AAAAAAAAB-U/lxTwKWc7T9MJhUtcRMh1mn9m_Ftjox9XwCLcB/s1600/note_2.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/hollycrypt-ransomware.html" - ] - }, - "uuid": "b77298c1-3f84-4ffb-a81b-36eab5c10881", - "value": "Hollycrypt Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".BTC" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/--7M0dtKhOio/WBxJx1PflYI/AAAAAAAAB-g/DSdMjLDLnVwwaMBW4H_98SzSJupLYm9WgCLcB/s1600/note_2.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/btclocker-ransomware.html" - ], - "synonyms": [ - "BTC Ransomware" - ] - }, - "uuid": "3f461284-85a1-441c-b07d-8b547be43ca2", - "value": "BTCLocker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. From the developer behind the Apocalypse Ransomware, Fabiansomware, and Esmeralda", - "meta": { - "date": "November 2016", - "encryption": "AES", - "extensions": [ - ".crypted_file" - ], - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes-filenames": [ - "filename.Instructions_Data_Recovery.txt" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-1jyI1HoqJag/WBzj9SLvipI/AAAAAAAAB_U/_sp8TglWEPQphG8neqrztfUUIjcBbVhDwCLcB/s1600/kangaroo-lock_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/kangaroo-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-kangaroo-ransomware-not-only-encrypts-your-data-but-tries-to-lock-you-out-of-windows/" - ] - }, - "uuid": "5ab1449f-7e7d-47e7-924a-8662bc2df805", - "value": "Kangaroo Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".dCrypt" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-2rS0Yq27wp0/WBtKfupZ2sI/AAAAAAAAB8I/0MR-9Xx0n-0zV_NBSScDCiYTp1KH-edtACLcB/s1600/Lockscreen_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/dummyencrypter-ransomware.html" - ] - }, - "uuid": "6bf055c6-acb2-4459-92b0-70d61616ab62", - "value": "DummyEncrypter Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".dCrypt" - ], - "payment-method": "Email", - "ransomnotes": [ - "YOUR FILES ARE ENCRYPTED THAT THEIR DECRYPT SEND EMAIL US AT encryptss77@gmail.com IN MESSAGE INDICATE IP ADDRESS OF COMPUTER WHERE YOU SAW THIS MESSAGE YOU CAN FIND IT ON 2IP.RU WE WILL REPLY TO YOU WITHIN 24 HOURS" - ], - "refs": [ - "http://virusinfo.info/showthread.php?t=201710", - "https://id-ransomware.blogspot.co.il/2016/11/encryptss77-ransomware.html" - ], - "synonyms": [ - "SFX Monster Ransomware" - ] - }, - "uuid": "317cab8a-31a1-4a82-876a-94edc7afffba", - "value": "Encryptss77 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".ace" - ], - "payment-method": "Website (onion)", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-zb0TP0wza7I/WBpShN0tCMI/AAAAAAAAB64/oTkSFwKFVx8hY1rEs5FQU6F7oaBW-LqHwCLcB/s1600/note_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/winrarer-ransomware.html" - ] - }, - "uuid": "7ee22340-ed89-4e22-b085-257bde4c0fc5", - "value": "WinRarer Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".blackblock" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1", - "ransomnotes": [ - "YOUR FILES HAVE BEEN ENCRYPTED! Your personal ID ***** Your file have been encrypted with a powerful strain of a virus called ransomware. Your files are encrypted using the same methods banks and the military use. There is currently no possible way to decrypt files with the private key. Lucky for you, we can help. We are willing to sell you a decryptor UNIQUELY made for your computer (meaning someone else's decryptor will not work for you). Once you pay a small fee, we will instantly send you the software/info necessary to decrypt all your files, quickly and easily." - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/russian-globe-ransomware.html" - ] - }, - "uuid": "30771cde-2543-4c13-b722-ff940f235b0f", - "value": "Russian Globe Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "November 2016", - "encryption": "AES-256", - "extensions": [ - ".zn2016" - ], - "payment-method": "Bitcoin", - "price": "10 (7300 $)", - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-0AGEY4vAlA0/WBi_oChzFNI/AAAAAAAAB4w/8PrPRfFU30YFWCwHzqnsx4bYISVNFyesQCLcB/s1600/note.PNG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/11/zerocrypt-ransomware.html" - ] - }, - "uuid": "e999ca18-61cb-4419-a2fa-ab8af6ebe8dc", - "value": "ZeroCrypt Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "RSA", - "extensions": [ - ".c400", - ".c300", - "!@!@!@_contact mail___boroznsalyuda@gmail.com___!@!@.psd", - "!@#$_____ISKANDER@TUTAMAIL.COM_____$#@!.RAR", - "!@#$%^&-()_+.1C" - ], - "payment-method": "Bitcoin", - "price": "7 (2000 - 5000 $)", - "ransomnotes": [ - "Good day Your files were encrypted/locked As evidence can decrypt file 1 to 3 1-30MB The price of the transcripts of all the files on the server: 7 Bitcoin Recommend to solve the problem quickly and not to delay Also give advice on how to protect Your server against threats from the network (Files sql mdf backup decryption strictly after payment)!", - "Для связи с нами используйте почту\ninkognitoman@tutamail.com\ninkognitoman@firemail.cc" - ], - "ransomnotes-filenames": [ - "INFO.txt" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/rotorcrypt-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/", - "https://twitter.com/demonslay335/status/1050117756094476289" - ], - "synonyms": [ - "RotorCrypt", - "RotoCrypt", - "Tar Ransomware" - ] - }, - "uuid": "63991ed9-98dc-4f24-a0a6-ff58e489c263", - "value": "RotorCrypt(RotoCrypt, Tar) Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.", - "meta": { - "date": "October 2016", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - "ISHTAR-. (prefix)" - ], - "payment-method": "Email - rubles", - "price": "15 000", - "ransomnotes": [ - "FOR FILE DISCRIPTION, PLEASE CONTACT YOU@edtonmail@protonmail.com Or BM-NBYR3ctSgr67iciT43rRNmHdHPAYBBK7 USING BITMESSAGE DESKTOP OR https://bitmsg.me/ BASIC TECHNICAL DETAILS: > Standard encryption order: AES 256 + RSA 2048. > A unique AES key is created for each file. > Decryption is impossible without the ISHTAR.DATA file (see% APPDATA% directory). ----- TO DECRYPT YOUR FILES PLEASE WRITE TO youneedmail@protonmail.com OR TO BM-NBYR3ctSgr67iciT43rRNmHdHPAYBBK7 USING BITMESSAGE DESKTOP OR https://bitmsg.me/ BASIC TECHNICAL DETAILS: > Standart encryption routine: AES 256 + RSA 2048. > Every AES key is unique per file. > Decryption is impossible without ISHTAR.DATA file (see% APPDATA% path)." - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/ishtar-ransomware.html" - ] - }, - "uuid": "30cad868-b2f1-4551-8f76-d17695c67d52", - "value": "Ishtar Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "extensions": [ - ".hcked" - ], - "payment-method": "rupies", - "price": "3500 - 5000 - 10 000", - "ransomnotes": [ - "IMPORTANT!!!! All of your computer files have been encrypted. DO NOT CHANGE ANY FILES! We can restore all the files. How to restore files: - \n1) Follow this link: - http://goo.gl/forms/VftoBRppkJ \n2) Fill out the form above. \n3) For 24 hours on your email + mobile SMS will come instructions for solving the problem. Thank you! DarkWing020" - ], - "ransomnotes-filenames": [ - "CreatesReadThisFileImportant.txt" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-gqEyoqXbZnE/WBXoF5bPZZI/AAAAAAAAB2U/YGpgIdjXyQQeDnwc9PlJs37YWtWTnH_wgCLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/masterbuster-ransomware.html", - "https://twitter.com/struppigel/status/791943837874651136" - ] - }, - "uuid": "07f859cd-9c36-4dae-a6fc-fa4e4aa36176", - "value": "MasterBuster Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "extensions": [ - ".coin" - ], - "payment-method": "Bitcoin", - "price": "3", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-oaElZvUqbfo/WBUOGdD8unI/AAAAAAAAB1w/Ya1_qq0gfa09AhRddUITQNRxKloXgD_BwCLcB/s1600/wallp.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/jackpot-ransomware.html", - "https://twitter.com/struppigel/status/791639214152617985", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-28-2016-locky-angry-duck-and-more/" - ], - "synonyms": [ - "Jack.Pot Ransomware" - ] - }, - "uuid": "04f1772a-053e-4f6e-a9af-3f83ab312633", - "value": "JackPot Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Georgian ransomware", - "meta": { - "date": "October 2016", - "extensions": [ - ".Encryption:" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "ransomnotes": [ - "All your files are encrypted, but do not worry, they have not been removed. (for now) You have 24 hours to pay $100. Money move to the specified Bitcoin -account. Otherwise, all files will be destroyed. Do not turn off the computer and/or do not attempt to disable me. When disobedience will be deleted 100 files." - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-cukkC4KAhZE/WBY1jJbcQoI/AAAAAAAAB3I/p8p-iNQRnQwnP6c6H77h_SHMQNAlkJ1CgCLcB/s1600/onyx.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/onyx-ransomware.html", - "https://twitter.com/struppigel/status/791557636164558848", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-28-2016-locky-angry-duck-and-more/" - ] - }, - "uuid": "927a4150-9380-4310-9f68-cb06d8debcf2", - "value": "ONYX Ransomeware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".inf643" - ], - "payment-method": "Bitcoin", - "price": "1000 $", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-JuBZKpEHV0Q/WBYNHFlW7pI/AAAAAAAAB20/z0DPYA_8l6U8tB6pbgo8ZwyIJRcrIVy2ACLcB/s1600/Note1.JPG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/ifn643-ransomware.html", - "https://twitter.com/struppigel/status/791576159960072192", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-28-2016-locky-angry-duck-and-more/" - ] - }, - "uuid": "ddeab8b3-5df2-414e-9c6b-06b309e1fcf4", - "value": "IFN643 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".Alcatraz" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "ransomed.hTmL" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-b0-Uvnz703Q/WBcMGkZqtwI/AAAAAAAAB3Y/a6clIjdp_tI2T-OE_ykyjvB2qNY3gqWdQCLcB/s1600/Screenshot_1.jpg", - "https://2.bp.blogspot.com/-y5a6QnjAiv0/WBcMKV0zDDI/AAAAAAAAB3c/ytOQHJgmy30H_jEWPcfht7RRsh4NhcrvACLcB/s1600/Screenshot_2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/alcatraz-locker-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-4th-2016-cerber-paydos-alcatraz-locker-and-more/", - "https://twitter.com/PolarToffee/status/792796055020642304" - ] - }, - "uuid": "2ad63264-8f52-4ab4-ad26-ca8c3bcc066e", - "value": "Alcatraz Locker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".encrypted" - ], - "payment-method": "Email", - "ransomnotes": [ - "Windows has encountered a critical problem and needs your immediate action to recover your data. The system access is locked and all the data have been encrypted to avoid the information be published or misused. You will not be able to access to your files and ignoring this message may cause the total loss of the data. We are sorry for the inconvenience. You need to contact the email below to restore the data of your system. Email: esmeraldaencryption@mail.ru You will have to order the Unlock-Password and the Esmeralda Decryption Software. All the instructions will be sent to you by email." - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-vaWu8OjSiXE/WBzkLBdB8DI/AAAAAAAAB_Y/k8vvtYEIdTkFJhruRJ6qDNAujAn4Ph-xACLcB/s1600/esmeralda-lock_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/esmeralda-ransomware.html", - "https://www.bleepingcomputer.com/forums/t/630835/esmeralda-ransomware/" - ] - }, - "uuid": "ff5a04bb-d412-4cb3-9780-8d3488b7c268", - "value": "Esmeralda Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "0.053773", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-_jxt6kCRnwM/WBNf7mi92nI/AAAAAAAAB0g/homx8Ly379oUKAOIhZU6MxCiWX1gA_TkACLcB/s1600/wallp.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/encryptile-ransomware.html" - ] - }, - "uuid": "56e49b84-a250-4aaf-9f65-412616709652", - "value": "EncrypTile Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Sample of how the hacker tricks the user using the survey method. https://1.bp.blogspot.com/-72ECd1vsUdE/WBMSzPQEgzI/AAAAAAAABzA/i8V-Kg8Gstcn_7-YZK__PDC2VgafWcfDgCLcB/s1600/survey-screen.png The hacker definatly has a sense of humor: https://1.bp.blogspot.com/-2AlvtcvdyUY/WBMVptG_V5I/AAAAAAAABzc/1KvAMeDmY2w9BN9vkqZO8LWkBu7T9mvDACLcB/s1600/ThxForYurTyme.JPG", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".encrypted" - ], - "payment-method": "Game", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-GAPCc3ITdQY/WBMTmJ4NaRI/AAAAAAAABzM/XPbPZvZ8vbUrOWxtwPmfHFJiNT_2gfaOgCLcB/s1600/fileice-source.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/fileice-ransomware-survey.html", - "https://www.bleepingcomputer.com/news/security/in-dev-ransomware-forces-you-do-to-survey-before-unlocking-computer/" - ] - }, - "uuid": "ca5d0e52-d0e4-4aa9-872a-0669433c0dcc", - "value": "Fileice Ransomware Survey Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256", - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "0.29499335", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-vIMgkn8WVJM/WBJAxkbya7I/AAAAAAAABys/tCpaTOxfGDw8A611gudDh46mhZT70dURwCLcB/s1600/lock-screen.jpg", - "https://1.bp.blogspot.com/-b0QiEQec0Pg/WBMf2HG6hjI/AAAAAAAABz8/BtN2-INZ2KQ4W2_iPqvDZTtlA0Aq_4gVACLcB/s1600/Screenshot_2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/cryptowire-ransomware.html", - "https://twitter.com/struppigel/status/791554654664552448", - "https://www.bleepingcomputer.com/news/security/-proof-of-concept-cryptowire-ransomware-spawns-lomix-and-ultralocker-families/" - ] - }, - "uuid": "4e6e45c2-8e13-49ad-8b27-e5aeb767294a", - "value": "CryptoWire Ransomeware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Based on Locky", - "meta": { - "date": "October 2016", - "encryption": "AES-128+RSA", - "extensions": [ - ".locky", - "[a-zA-Z0-9+_-]{1,}.[a-z0-9]{3,4}.locky" - ], - "payment-method": "Email", - "ransomnotes": [ - "!!! IMPORTANT INFORMATION !!!! All files are encrypted using RSA-3072 and AES128 encryption. You can learn more about RSA and AES ciphers here: Https://hu.wikipedia.org/wiki/RSA-eljárás Https://hu.wikipedia.org/wiki/Advanced_Encryption_Standard To return files, you need to get a secret key and decryption program. To get the key, please follow these steps: \n1. Send an identification code to the email address locky@mail2tor.com! If you want, send a 1 MB file for decryption. In order to prove that we can recover data. (Please, email must contain only the identification code, as well as the attachment) \n3. Please note, check the mail, we will send you an email within 24 hours! You will receive a decrypted file and decryption program in the attachment. Follow the instructions in the email.!!! Your identification code !!!" - ], - "ransomnotes-filenames": [ - "_Adatok_visszaallitasahoz_utasitasok.txt", - "_locky_recover_instructions.txt" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-lLZZBScC27U/WBmkDQzl9FI/AAAAAAAAB5Y/gozOy17Yv0EWNCQVSOXn-PkTccYZuMmPQCLcB/s1600/note-bmp_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/hucky-ransomware-hungarian-locky.html", - "https://blog.avast.com/hucky-ransomware-a-hungarian-locky-wannabe", - "https://twitter.com/struppigel/status/846241982347427840" - ], - "synonyms": [ - "Hungarian Locky Ransomware" - ] - }, - "uuid": "74f91a93-4f1e-4603-a6f5-aaa40d2dd311", - "value": "Hucky Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".wnx" - ], - "payment-method": "Bitcoin", - "price": "2 - 4", - "ransomnotes": [ - "Your files are encrypted! Your files have been safely encrypted on this PC: photos, documents, databases, etc. Encryption was produced using a unique public key generated for this computer. To decrypt files you need to obtain the private key. The only way to get the private key is to pay 4 BTC. You saved it on qualified system administrator who could make your network safe and secure. In order to decrypt the files send your bitcoins to the following address: 13gYXFxpzm7hAd4esdnJGt9JvYqyD1Y6by After you complete your payment, send an email to 6214ssxpvo@sigaint.org with YOUR ID as subject (ID is in the end of the file) and you'll receive private key, needed software and step by step guide in 1 business day. Offer is valid for 5 business days (expiration date is in the end of the file). AFTER TIME IS UP, PRICE DOUBLES. No discounts, no other payment methods. How to buy bitcoins? \n1. Create a Bitcoin Wallet (we recommend Blockchain.info) \n2. Buy necessary amount of Bitcoins Do not forget about the transaction commission in the Bitcoin network (= 0.0005). Here are our recommendations: LocalBitcoins.com – the fastest and easiest way to buy and sell Bitcoins; CoinCafe.com – the simplest and fastest way to buy, sell and use Bitcoins; BTCDirect.eu – the best for Europe; CEX.IO – Visa / MasterCard; CoinMama.com – Visa / MasterCard; HowToBuyBitcoins.info – discover quickly how to buy and sell bitcoins in your local currency. More questions? Send an email to 6214ssxpvo@sigaint.org ID: *** EXP DATE: Sept. 12 2016 Winnix Cryptor Team" - ], - "ransomnotes-filenames": [ - "YOUR FILES ARE ENCRYPTED!.txt" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/winnix-cryptor-ransomware.html", - "https://twitter.com/PolarToffee/status/811940037638111232" - ] - }, - "uuid": "e30e663d-d8c8-44f2-8da7-03b1a9c52376", - "value": "Winnix Cryptor Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Demands 10 BTC", - "meta": { - "date": "October 2016", - "encryption": "AES-512", - "extensions": [ - ".adk" - ], - "payment-method": "Bitcoin", - "price": "10 (7300 $)", - "ransomnotes": [ - "ANGRY DUCK! All your important files have been encrypted using very string cryptography (AES-512 With RSA-64 FIPS grade encryption). To recover your files, send 10 BTC to my private wallet DON'T MESS WITH THE DUCKS!!!" - ], - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-k3s85Fx9N_E/WBIfuUNTMmI/AAAAAAAAByM/rQ10tKuXTlEJfLTOoBwJPo7rhhaiK2OoQCLcB/s1600/screen-lock.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/angryduck-ransomware.html", - "https://twitter.com/demonslay335/status/790334746488365057" - ] - }, - "uuid": "2813a5c7-530b-492f-8d77-fe7b1ed96a65", - "value": "AngryDuck Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-512", - "extensions": [ - ".lock93" - ], - "payment-method": "Email", - "price": "1000 rubles", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-WuD2qaaNIb0/WA4_g_FnIfI/AAAAAAAABx4/pn6VNqMXMzI_ryvKUruY3ctYtzomT1I4gCLcB/s1600/note3.jpg", - "https://1.bp.blogspot.com/-S6M83oFxSdM/WA4_ak9WATI/AAAAAAAABx0/3FL3q21FdxMQvAgrr2FORQIaNtq2-P2jACLcB/s1600/note2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/lock93-ransomware.html", - "https://twitter.com/malwrhunterteam/status/789882488365678592" - ] - }, - "uuid": "2912426d-2a26-4091-a87f-032a6d3d28c1", - "value": "Lock93 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-512", - "payment-method": "Bitcoin", - "price": "0.25 - 0.5", - "ransomnotes-filenames": [ - "!!!!!readme!!!!!.htm" - ], - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-5gZpxeEWqZg/WBeNnEP9GzI/AAAAAAAAB4g/ELCCp88whLMI6CzpGTjlxbmXBMFIKhwtwCLcB/s1600/onion-site.JPG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/asn1-encoder-ransomware.html", - "https://malwarebreakdown.com/2017/03/02/rig-ek-at-92-53-105-43-drops-asn1-ransomware/" - ] - }, - "uuid": "dd99cc50-91f7-4375-906a-7d09c76ee9f7", - "value": "ASN1 Encoder Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. The hacker tries to get the user to play a game and when the user clicks the button, there is no game, just 20 pictures in a .gif below: https://3.bp.blogspot.com/-1zgO3-bBazs/WAkPYqXuayI/AAAAAAAABxI/DO3vycRW-TozneSfRTdeKyXGNEtJSMehgCLcB/s1600/all-images.gif", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".hacked" - ], - "payment-method": "Email Bitcoin", - "ransomnotes": [ - "All right my dear brother!!! Enough free playing. Your files have been encrypted. Pay so much this much money so I can send you the password for your files. I can be paid this much too cause I am very kind. So move on I didn't raise the price." - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/click-me-ransomware.html", - "https://www.youtube.com/watch?v=Xe30kV4ip8w" - ] - }, - "uuid": "97bdadda-e874-46e6-8672-11dbfe3958c4", - "value": "Click Me Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - ".hacked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-4HNc9S8SY4I/WBMkpdKyDsI/AAAAAAAAB0I/udESgro7YB4pF98Dv2KrrecyymFGsvV2QCLcB/s1600/note.JPG" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/airacrop-ransomware.html" - ] - }, - "uuid": "e7a5c384-a93c-4ed4-8411-ca1e52396256", - "value": "AiraCrop Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Base64 encoding, ROT13, and top-bottom swapping", - "meta": { - "date": "October 2016", - "encryption": "AES-256 + RSA-2048", - "extensions": [ - "#LOCK#" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-sdlDK4OIuPA/WAehWZYHaMI/AAAAAAAABvc/TcAcLG2lw10aOFY3FbP1A5EuLjL6LR62ACLcB/s1600/note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/japanlocker-ransomware.html", - "https://www.cyber.nj.gov/threat-profiles/ransomware-variants/japanlocker", - "https://github.com/fortiguard-lion/schRansomwareDecryptor/blob/master/schRansomwarev1_decryptor.php", - "https://blog.fortinet.com/2016/10/19/japanlocker-an-excavation-to-its-indonesian-roots" - ], - "synonyms": [ - "SHC Ransomware", - "SHCLocker", - "SyNcryption" - ] - }, - "uuid": "d579e5b6-c6fd-43d9-9213-7591cd324f94", - "value": "JapanLocker Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. EDA2", - "meta": { - "date": "October 2016", - "encryption": "AES(256)", - "extensions": [ - ".coded" - ], - "payment-method": "Bitcoin", - "price": "1 - 2.5 - 3", - "ransomnotes-filenames": [ - "Decryption Instructions.txt" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-0YMsPH5WuTk/WAepI4BnqZI/AAAAAAAABv0/yXt4tdrmmAIf-N9KUmehY6mK1kTV-eFFQCLcB/s1600/note-wal2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/anubis-ransomware.html", - "http://nyxbone.com/malware/Anubis.html" - ] - }, - "uuid": "a6215279-37d8-47f7-9b1b-efae4178c738", - "value": "Anubis Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256", - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes": [ - "Attention! ! ! All of your copies of your system have been permanently deleted and the data on all partitions and workstations have been encrypted! Stay calm. You can recover all your data by making a payment of 2 BTC (1200 USD) in Bitcoin currency to receive a decryption key. To purchase Bitcions you can use www.coinbase.com After buying BTC send the equivalent of 2 BTC (1200 USD) to our BTC adress : 16jX5RbF2pEcLYHPukazWhDCkxXTs7ZCxB After payment contact us to receive your decryption key. In mail title write your unique ID: {custom id visually resembling a MAC address} Our e-mail: crypt302@gmx.com" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/xtplocker-ransomware.html" - ] - }, - "uuid": "eef4bf49-5b1d-463a-aef9-538c5dc2f71f", - "value": "XTPLocker 5.0 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. Also encrypts executables", - "meta": { - "date": "October 2016", - "encryption": "AES-128", - "extensions": [ - ".exotic", - "random.exotic" - ], - "payment-method": "Bitcoin", - "price": "50 $", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-WJYR7LkWHWY/WAaCYScljOI/AAAAAAAABuo/j18AGhzv7WUPb2r4HWkYm4TPgYw9S5PUwCLcB/s1600/note1-1.jpg", - "https://4.bp.blogspot.com/-2QxJ3KCRimI/WAaCcWcE2uI/AAAAAAAABus/9SGRY5iQT-ITfG_JrY7mn6-PUpQrSKg7gCLcB/s1600/note1-2.jpg", - "https://3.bp.blogspot.com/-SMXOoWiGkxw/WAaGOMdecrI/AAAAAAAABu8/S-YjlWlPKbItSN_fe8030tMDHWzouHsIgCLcB/s1600/note2.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/eviltwins-exotic-ransomware-targets-executable-files/", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-14-2016-exotic-lockydump-comrade-and-more/", - "https://www.cyber.nj.gov/threat-profiles/ransomware-variants/exotic-ransomware", - "https://id-ransomware.blogspot.co.il/2016/10/exotic-ransomware.html" - ] - }, - "uuid": "eb22cb8d-763d-4cac-af35-46dc4f85317b", - "value": "Exotic Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. NO POINT TO PAY THE RANSOM, THE FILES ARE COMPLETELY DESTROYED", - "meta": { - "date": "October 2016", - "encryption": "AES-128", - "extensions": [ - ".dll" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-VTUhk_Py2FA/WAVCO1Yn69I/AAAAAAAABuI/N71wo2ViOE0UjrIdbeulBRTJukHtA2TdACLcB/s1600/ransom-note.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/apt-ransomware-2.html" - ] - }, - "uuid": "6ec0f43c-6b73-4f5e-bee7-a231572eb994", - "value": "APT Ransomware v.2" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256", - "extensions": [ - ".enc" - ], - "payment-method": "Bitcoin", - "price": "0.0523", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-NfRePJbfjbY/WAe5LHFsWaI/AAAAAAAABwE/1Pk116TDqAYEDYvnu2vzim1l-H5seW9mQCLcB/s1600/note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/ws-go-ransonware.html", - "https://www.cyber.nj.gov/threat-profiles/ransomware-variants/apt-ransomware-v2" - ], - "synonyms": [ - "WS Go Ransonware", - "Trojan.Encoder.6491" - ] - }, - "related": [ - { - "dest-uuid": "f855609e-b7ab-41e8-aafa-62016f8f4e1a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "a57a8bc3-8c33-43e8-b237-25edcd5f532a", - "value": "Windows_Security Ransonware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES", - "extensions": [ - ".NCRYPT", - ".ncrypt" - ], - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-k7T79DnBk8w/WBc67QXyjWI/AAAAAAAAB3w/QbA-E9lYdSMOg3PcG9Vz8fTc_OhmACObACLcB/s1600/note-html.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/ncrypt-ransomware.html" - ] - }, - "uuid": "d590865e-f3ae-4381-9d82-3f540f9818cb", - "value": "NCrypt Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. In devVenisRansom@protonmail.com", - "meta": { - "date": "October 2016", - "encryption": "AES-2048", - "extensions": [ - ".venis" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-IFEOWjw-aaQ/WAXTu9oEN4I/AAAAAAAABuY/APqBiaHn3pAX8404Noyuj7tnFJDf2m_XACLcB/s1600/note1.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/venis-ransomware.html", - "https://twitter.com/Antelox/status/785849412635521024", - "http://pastebin.com/HuK99Xmj" - ] - }, - "uuid": "b9cfe6f3-5970-4283-baf4-252e0491b91c", - "value": "Venis Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-128", - "extensions": [ - ".1txt" - ], - "payment-method": "Bitcoin", - "price": "200 $", - "ransomnotes": [ - "We encrypt important files on your computer: documents, databases, photos, videos and keys. Files encryption algorithm AES 128 (https://ru.wikipedia.org/wiki/Advanced_Encryption_Standard) with a private key that only we know. Encrypted files have .1txt extension. It decrypts files without the private key IMPOSSIBLE. \nIf you want to get the files back: \n1) Install the Tor Browser http://www.torproject.org/ \n2) Locate the desktop key to access E_N_I_G_M_A.RSA site (password is encrypted in the key of your files) \n3) Go to the website http://kf2uimw5omtgveu6.onion/ into a torus-browser and log in using E_N_I_G_M_A.RSA \n4) Follow the instructions on the website and download the decoder \nC:\\Documents and Settings\\Администратор\\Рабочийстол\\E_N_I_G_M_A.RSA - The path to the key file on the desktop C:\\DOCUME~1\\9335~1\\LOCALS~1\\Temp\\E_N_I_G_M_A.RSA - The path to the key file in TMP directory" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/enigma-2-ransomware.html" - ] - }, - "uuid": "507506a3-3745-47fd-8d31-ef122317c0c2", - "value": "Enigma 2 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc.. sample is set to encrypt only in 2017...", - "meta": { - "date": "October 2016", - "encryption": "AES-256", - "payment-method": "Bitcoin", - "price": "500$", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-XZiiaCYM9Bk/WAUsUkrCJEI/AAAAAAAABtk/z-sMHflz3Q8_aWc-K9PD0N5TGkSGwwQnACLcB/s1600/note-html.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/deadly-ransomware.html", - "https://twitter.com/malwrhunterteam/status/785533373007728640" - ], - "synonyms": [ - "Deadly for a Good Purpose Ransomware" - ] - }, - "uuid": "a25e39b0-b601-403c-bba8-2f595e221269", - "value": "Deadly Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256", - "extensions": [ - ".comrade" - ], - "payment-method": "Bitcoin", - "price": "~2", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-MmzOC__9qPA/V__t2kNX-SI/AAAAAAAABrc/t8ypPa1jCIUbPfvR7UGbdGzdvKrbAv_DgCLcB/s1600/wallpaper.jpg", - "https://4.bp.blogspot.com/-hRoC-UFr-7o/V__tAEFuZWI/AAAAAAAABrQ/xDawlulx8Bg4uEtX4bU2ezPMY-x6iFiuQCLcB/s1600/note-1ch.JPG", - "https://4.bp.blogspot.com/-PdYtm6sRHAI/WAEngHQBg_I/AAAAAAAABsA/nh8m7__b0wgviTEBahyNYK4HFhF1v7rOQCLcB/s1600/icon-stalin-2.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/comrade-circle-ransomware.html" - ] - }, - "uuid": "db23145a-e15b-4cf7-9d2c-ffa9928750d5", - "value": "Comrade Circle Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256 or Blowfish", - "extensions": [ - ".raid10", - ".[random].raid10", - ".blt", - ".globe", - ".[random].blt", - ".encrypted", - ".[random].globe", - ".[random].encrypted", - ".mia.kokers@aol.com", - ".[mia.kokers@aol.com]", - ".lovewindows", - ".openforyou@india.com", - ".." - ], - "payment-method": "Bitcoin", - "price": "0.8 - 1", - "ransomnotes-refs": [ - "https://3.bp.blogspot.com/-MYI30xhrcZU/V_qcDyASJsI/AAAAAAAABpU/Pej5jDk_baYBByLx1cXwFL8LBiT8Vj3xgCLcB/s1600/note22.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/globe2-ransomware.html", - "https://success.trendmicro.com/portal_kb_articledetail?solutionid=1114221" - ], - "synonyms": [ - "Purge Ransomware" - ] - }, - "related": [ - { - "dest-uuid": "fe16edbe-3050-4276-bac3-c7ff5fd4174a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "5541471c-8d15-4aec-9996-e24b59c3e3d6", - "value": "Globe2 Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256", - "extensions": [ - ".k0stya" - ], - "payment-method": "PaySafe", - "price": "300 CZK - 2000 CZK after 12 hours", - "ransomnotes-refs": [ - "https://2.bp.blogspot.com/-E_MI2fT33J0/V_k_9Gjkj4I/AAAAAAAABpA/-30UT5HhPAAR9YtVkFwgrYqLIdWPprZ9gCLcB/s1600/lock-screen.jpg", - "https://2.bp.blogspot.com/-4YmIkWfYfRA/V_lAALhfSvI/AAAAAAAABpE/Dj35aroKXSwbLXrSPqGCzbvhsTNHdsbAgCLcB/s1600/kostya.jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/kostya-ransomware.html", - "http://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-14-2016-exotic-lockydump-comrade-and-more/" - ] - }, - "uuid": "7d6f02d2-a626-40f6-81c3-14e3a9a2aea5", - "value": "Kostya Ransomware" - }, - { - "description": "This is most likely to affect English speaking users, since the note is written in English. English is understood worldwide, thus anyone can be harmed. The hacker spread the virus using email spam, fake updates, and harmful attachments. All your files are compromised including music, MS Office, Open Office, pictures, videos, shared online files etc..", - "meta": { - "date": "October 2016", - "encryption": "AES-256 CBC", - "extensions": [ - ".comrade" - ], - "payment-method": "Bitcoin", - "price": "1.5", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-nskzYgbg7Ac/V_jpJ3GApqI/AAAAAAAABos/EbG_-BLDPqA9bRVOWdzHjPnDWFiHYlsJwCLcB/s1600/ransom-note.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/10/fs0ciety-locker-ransomware.html" - ] - }, - "uuid": "ed3a4f8a-49de-40c3-9acb-da1b78f89c4f", - "value": "Fs0ciety Locker Ransomware" - }, - { - "description": "It’s directed to English speaking users, therefore is able to infect worldwide. It is spread using email spam, fake updates, attachments and so on. It encrypts all your files, including: music, MS Office, Open Office, pictures, videos, shared online files etc.. After the files are decrypted, the shadow files are deleted using the following command: vssadmin.exe Delete Shadows /All /Quiet", - "meta": { - "date": "September 2016", - "encryption": "AES", - "extensions": [ - ".ecrypt" - ], - "payment-method": "Tor WebSite", - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-E9WbSxLgaYs/WGn8gC6EfvI/AAAAAAAAC8A/bzd7uP9fcxU6Fyq1n6-9ZbUUGWlls9lrwCLcB/s1600/note-txt_2.png" - ], - "refs": [ - "https://id-ransomware.blogspot.co.il/2016/09/erebus-ransomware.html" - ] - }, - "uuid": "6a77c96b-1814-427f-83ca-fe7e0e40b1c0", - "value": "Erebus Ransomware" - }, - { - "description": "According to numerous open-source reports, a widespread ransomware campaign is affecting various organizations with reports of tens of thousands of infections in as many as 74 countries, including the United States, United Kingdom, Spain, Russia, Taiwan, France, and Japan. The software can run in as many as 27 different languages. The latest version of this ransomware variant, known as WannaCry, WCry, or Wanna Decryptor, was discovered the morning of May 12, 2017, by an independent security researcher and has spread rapidly over several hours, with initial reports beginning around 4:00 AM EDT, May 12, 2017. Open-source reporting indicates a requested ransom of .1781 bitcoins, roughly $300 U.S.", - "meta": { - "date": "May 2017", - "payment-method": "Bitcoin", - "price": "0.1781 (300$ - $600)", - "refs": [ - "https://gist.github.com/rain-1/989428fa5504f378b993ee6efbc0b168" - ], - "synonyms": [ - "WannaCrypt", - "WannaCry", - "WanaCrypt0r", - "WCrypt", - "WCRY" - ] - }, - "related": [ - { - "dest-uuid": "ad67ff31-2a02-43f9-8b12-7df7e4fcccd6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "d62ab8d5-4ba1-4c45-8a63-13fdb099b33c", - "value": "WannaCry" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES(256)", - "extensions": [ - ".enc" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "YOUR_FILES_ARE_LOCKED.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/CryptoHasYou.html" - ] - }, - "uuid": "a0ce5d94-a22a-40db-a09f-a796d0bb4006", - "value": ".CryptoHasYou." - }, - { - "description": "Ransomware", - "meta": { - "encryption": "XOR", - "extensions": [ - ".777", - "._[timestamp]_$[email]$.777", - "e.g. ._14-05-2016-11-59-36_$ninja.gaiver@aol.com$.777" - ], - "payment-method": "Bitcoin", - "price": "0.1 (37$)", - "ransomnotes-filenames": [ - "read_this_file.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/777" - ], - "synonyms": [ - "Sevleg" - ] - }, - "uuid": "cd9e9eaa-0895-4d55-964a-b53eacdfd36a", - "value": "777" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".R4A", - ".R5A" - ], - "payment-method": "Bitcoin", - "price": "13 (4980$)", - "ransomnotes-filenames": [ - "FILES_BACK.txt" - ], - "refs": [ - "https://github.com/hasherezade/malware_analysis/tree/master/7ev3n", - "https://www.youtube.com/watch?v=RDNbH5HDO1E&feature=youtu.be", - "http://www.nyxbone.com/malware/7ev3n-HONE$T.html" - ], - "synonyms": [ - "7ev3n-HONE$T" - ] - }, - "related": [ - { - "dest-uuid": "ac2608e9-7851-409f-b842-e265b877a53c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "664701d6-7948-4e80-a333-1d1938103ba1", - "value": "7ev3n" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".8lock8" - ], - "ransomnotes-filenames": [ - "READ_IT.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/614025/8lock8-help-support-topic-8lock8-read-ittxt/" - ] - }, - "uuid": "b70b6537-cf00-4bd1-a4e9-ae5ff2eb7504", - "value": "8lock8" - }, - { - "description": "Ransomware related to TeamXRat", - "meta": { - "extensions": [ - "._AiraCropEncrypted" - ], - "payment-method": "WebSite (onion) - Email", - "ransomnotes-filenames": [ - "How to decrypt your files.txt" - ], - "refs": [ - "https://twitter.com/PolarToffee/status/796079699478900736" - ] - }, - "uuid": "77919c1f-4ef8-41cd-a635-2d3118ade1f3", - "value": "AiraCrop" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".unavailable", - ".disappeared" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "Read_Me.Txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/al-namrood" - ] - }, - "uuid": "0040dca4-bf2e-43cb-89ae-ab1b50f1183d", - "value": "Al-Namrood" - }, - { - "description": "Ransomware Made by creators of Cerber", - "meta": { - "extensions": [ - ".bin" - ], - "payment-method": "Bitcoin", - "price": "1 (650$)", - "ransomnotes-filenames": [ - "README HOW TO DECRYPT YOUR FILES.HTML" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/new-alfa-or-alpha-ransomware-from-the-same-devs-as-cerber/", - "https://news.softpedia.com/news/cerber-devs-create-new-ransomware-called-alfa-506165.shtml" - ] - }, - "uuid": "888abc95-9e01-4cbc-a6e5-058eb9314f51", - "value": "ALFA Ransomware" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-128", - "extensions": [ - "random", - "random(x5)" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "Unlock_files_randomx5.html" - ], - "refs": [ - "https://cta-service-cms2.hubspot.com/ctas/v2/public/cs/c/?cta_guid=d4173312-989b-4721-ad00-8308fff353b3&placement_guid=22f2fe97-c748-4d6a-9e1e-ba3fb1060abe&portal_id=326665&redirect_url=APefjpGnqFjmP_xzeUZ1Y55ovglY1y1ch7CgMDLit5GTHcW9N0ztpnIE-ZReqqv8MDj687_4Joou7Cd2rSx8-De8uhFQAD_Len9QpT7Xvu8neW5drkdtTPV7hAaou0osAi2O61dizFXibewmpO60UUCd5OazCGz1V6yT_3UFMgL0x9S1VeOvoL_ucuER8g2H3f1EfbtYBw5QFWeUmrjk-9dGzOGspyn303k9XagBtF3SSX4YWSyuEs03Vq7Fxb04KkyKc4GJx-igK98Qta8iMafUam8ikg8XKPkob0FK6Pe-wRZ0QVWIIkM&hsutk=34612af1cd87864cf7162095872571d1&utm_referrer=https%3A%2F%2Finfo.phishlabs.com%2Fblog%2Falma-ransomware-analysis-of-a-new-ransomware-threat-and-a-decrypter&canon=https%3A%2F%2Finfo.phishlabs.com%2Fblog%2Falma-ransomware-analysis-of-a-new-ransomware-threat-and-a-decrypter&__hstc=61627571.34612af1cd87864cf7162095872571d1.1472135921345.1472140656779.1472593507113.3&__hssc=61627571.1.1472593507113&__hsfp=1114323283", - "https://info.phishlabs.com/blog/alma-ransomware-analysis-of-a-new-ransomware-threat-and-a-decrypter", - "http://www.bleepingcomputer.com/news/security/new-alma-locker-ransomware-being-distributed-via-the-rig-exploit-kit/" - ], - "synonyms": [ - "Alma Locker" - ] - }, - "uuid": "76a08868-345f-4566-a403-5f5e575dfee5", - "value": "Alma Ransomware" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".encrypt" - ], - "payment-method": "Itunes Gift Cards", - "price": "400$", - "ransomnotes-filenames": [ - "Read Me (How Decrypt) !!!!.txt" - ], - "refs": [ - "http://download.bleepingcomputer.com/demonslay335/AlphaDecrypter.zip", - "http://www.bleepingcomputer.com/news/security/decrypted-alpha-ransomware-continues-the-trend-of-accepting-amazon-cards/", - "https://twitter.com/malwarebread/status/804714048499621888" - ], - "synonyms": [ - "AlphaLocker" - ] - }, - "related": [ - { - "dest-uuid": "c1b9e8c5-9283-4dbe-af10-45956a446fb7", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "a27fff00-995a-4598-ba00-05921bf20e80", - "value": "Alpha Ransomware" - }, - { - "description": "Ransomware Websites only amba@riseup.net", - "meta": { - "extensions": [ - ".amba" - ], - "payment-method": "Bitcoin", - "price": "Depending on the victim’s situation", - "ransomnotes-filenames": [ - "ПРОЧТИ_МЕНЯ.txt", - "READ_ME.txt" - ], - "refs": [ - "https://twitter.com/benkow_/status/747813034006020096", - "https://www.enigmasoftware.com/ambaransomware-removal/" - ] - }, - "uuid": "8dd289d8-71bc-42b0-aafd-540dafa93343", - "value": "AMBA" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".AngleWare" - ], - "payment-method": "Bitcoin", - "price": "3", - "ransomnotes-filenames": [ - "READ_ME.txt" - ], - "refs": [ - "https://twitter.com/BleepinComputer/status/844531418474708993" - ] - }, - "uuid": "e06526ac-0083-44ab-8787-dd7278746bb6", - "value": "AngleWare" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "payment-method": "Write a FaceBook message", - "refs": [ - "https://twitter.com/struppigel/status/842047409446387714" - ], - "synonyms": [ - "ngocanh" - ] - }, - "uuid": "5b94100d-83bb-4e30-be7a-6015c00356e0", - "value": "Anony" - }, - { - "description": "Ransomware decryptionservice@mail.ru recoveryhelp@bk.ru ransomware.attack@list.ru esmeraldaencryption@mail.ru dr.compress@bk.ru", - "meta": { - "extensions": [ - ".encrypted", - ".SecureCrypted", - ".FuckYourData", - ".unavailable", - ".bleepYourFiles", - ".Where_my_files.txt", - "[filename].ID-*8characters+countrycode[cryptservice@inbox.ru].[random7characters]", - "*filename*.ID-[A-F0-9]{8}+countrycode[cryptcorp@inbox.ru].[a-z0-9]{13}" - ], - "payment-method": "Email - WebSite (onion)", - "ransomnotes-filenames": [ - "*.How_To_Decrypt.txt", - "*.Contact_Here_To_Recover_Your_Files.txt", - "*.Where_my_files.txt", - "*.Read_Me.Txt", - "*md5*.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/apocalypse", - "http://blog.emsisoft.com/2016/06/29/apocalypse-ransomware-which-targets-companies-through-insecure-rdp/" - ], - "synonyms": [ - "Fabiansomeware" - ] - }, - "related": [ - { - "dest-uuid": "d5d3f9de-21b5-482e-b716-5f2f13182990", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e87d9df4-b464-4458-ae1f-31cea40d5f96", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "e38b8876-5780-4574-9adf-304e9d659bdb", - "value": "Apocalypse" - }, - { - "description": "Ransomware Apocalypse ransomware version which uses VMprotect", - "meta": { - "extensions": [ - ".encrypted", - ".locked" - ], - "payment-method": "Email - WebSite (onion)", - "ransomnotes-filenames": [ - "*.How_To_Get_Back.txt" - ], - "refs": [ - "http://decrypter.emsisoft.com/download/apocalypsevm" - ] - }, - "uuid": "5bc9c3a5-a35f-43aa-a999-fc7cd0685994", - "value": "ApocalypseVM" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".locky" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1", - "ransomnotes-filenames": [ - "info.txt", - "info.html" - ], - "refs": [ - "https://decrypter.emsisoft.com/autolocky" - ] - }, - "uuid": "803fa9e2-8803-409a-b455-3a886c23fae4", - "value": "AutoLocky" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".enc" - ], - "refs": [ - "https://twitter.com/struppigel/status/828902907668000770" - ] - }, - "uuid": "dced0fe8-224e-47ef-92ed-5ab6c0536daa", - "value": "Aw3s0m3Sc0t7" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "2 (888,4$)", - "ransomnotes-filenames": [ - "Help Decrypt.html" - ], - "refs": [ - "https://decrypter.emsisoft.com/badblock", - "http://www.nyxbone.com/malware/BadBlock.html", - "http://www.nyxbone.com/images/articulos/malware/badblock/5.png" - ] - }, - "uuid": "f1a30552-21c1-46be-8b5f-64bd62b03d35", - "value": "BadBlock" - }, - { - "description": "Ransomware Based on my-Little-Ransomware", - "meta": { - "extensions": [ - ".adr" - ], - "refs": [ - "https://twitter.com/JakubKroustek/status/760482299007922176", - "https://0xc1r3ng.wordpress.com/2016/06/24/bakso-crypt-simple-ransomware/" - ] - }, - "uuid": "b21997a1-212f-4bbe-a6b7-3c703cbf113e", - "value": "BaksoCrypt" - }, - { - "description": "Ransomware Files might be partially encrypted", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".id-1235240425_help@decryptservice.info", - ".id-[ID]_[EMAIL_ADDRESS]" - ], - "payment-method": "Email - Telegram", - "ransomnotes-filenames": [ - "HOW TO DECRYPT.txt" - ], - "refs": [ - "https://reaqta.com/2016/03/bandarchor-ransomware-still-active/", - "https://www.bleepingcomputer.com/news/security/new-bandarchor-ransomware-variant-spreads-via-malvertising-on-adult-sites/" - ], - "synonyms": [ - "Rakhni" - ] - }, - "related": [ - { - "dest-uuid": "c85a41a8-a0a1-4963-894f-84bb980e6e86", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "af50d07e-3fc5-4014-9ac5-f5466cf042bc", - "value": "Bandarchor" - }, - { - "description": "Ransomware Possible affiliations with RockLoader, Locky and Dridex", - "meta": { - "extensions": [ - ".bart.zip", - ".bart", - ".perl" - ], - "payment-method": "Bitcoin", - "price": "3", - "ransomnotes-filenames": [ - "recover.txt", - "recover.bmp" - ], - "refs": [ - "http://now.avg.com/barts-shenanigans-are-no-match-for-avg/", - "http://phishme.com/rockloader-downloading-new-ransomware-bart/", - "https://www.proofpoint.com/us/threat-insight/post/New-Bart-Ransomware-from-Threat-Actors-Spreading-Dridex-and-Locky" - ], - "synonyms": [ - "BaCrypt" - ] - }, - "related": [ - { - "dest-uuid": "1dfd3ba6-7f82-407f-958d-c4a2ac055123", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "3cf2c880-e0b5-4311-9c4e-6293f2a566e7", - "value": "Bart" - }, - { - "description": "Ransomware Has a GUI. CryptoGraphic Locker family. Newer CoinVault variant.", - "meta": { - "extensions": [ - ".clf" - ], - "payment-method": "Bitcoin", - "price": "1", - "refs": [ - "https://noransom.kaspersky.com/", - "https://id-ransomware.blogspot.com/2016/05/bitcryptor-ransomware-aes-256-1-btc.html" - ] - }, - "uuid": "b5e9a802-cd17-4cd6-b83d-f36cce009808", - "value": "BitCryptor" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "Base64 + String Replacement", - "extensions": [ - ".bitstak" - ], - "payment-method": "Bitcoin", - "price": "0.07867 (40€)", - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/BitStakDecrypter.zip", - "https://id-ransomware.blogspot.com/2016/07/ransomware-007867.html" - ] - }, - "uuid": "33e398fa-2586-415e-9b18-6ea2ea36ff74", - "value": "BitStak" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".Silent" - ], - "payment-method": "Bitcoin", - "price": "0.07 (30$)", - "ransomnotes-filenames": [ - "Hacked_Read_me_to_decrypt_files.html", - "YourID.txt" - ], - "refs": [ - "http://nyxbone.com/malware/BlackShades.html", - "https://id-ransomware.blogspot.com/2016/06/silentshade-ransomware-blackshades.html" - ], - "synonyms": [ - "SilentShade", - "BlackShades" - ] - }, - "uuid": "bf065217-e13a-4f6d-a5b2-ba0750b5c312", - "value": "BlackShades Crypter" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".blocatto" - ], - "payment-method": "Bitcoin", - "price": "5 - 10", - "refs": [ - "http://www.bleepingcomputer.com/forums/t/614456/bloccato-ransomware-bloccato-help-support-leggi-questo-filetxt/" - ] - }, - "uuid": "a3e1cfec-aacd-4d84-aa7d-99ed6c17f26d", - "value": "Blocatto" - }, - { - "description": "Ransomware EXE was replaced to neutralize threat", - "meta": { - "synonyms": [ - "Salami" - ] - }, - "related": [ - { - "dest-uuid": "b95aa3fb-9f32-450e-8058-67d94f196913", - "payment-method": "Bitcoin", - "price": "1-2 / 7 after 1 week", - "refs": [ - "https://id-ransomware.blogspot.com/2016/05/booyah-ransomware-1-2-btc.html" - ], - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "eee75995-321f-477f-8b57-eee4eedf4ba3", - "value": "Booyah" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".lock" - ], - "payment-method": "Reais", - "price": "2000 (543$)", - "ransomnotes-filenames": [ - "MENSAGEM.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/brazilianRansom.html", - "http://www.nyxbone.com/images/articulos/malware/brazilianRansom/0.png" - ] - }, - "uuid": "f9cf4f0d-3efc-4d6d-baf2-7dcb96db1279", - "value": "Brazilian" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".id-%ID%_garryweber@protonmail.ch" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "HOW_OPEN_FILES.html" - ], - "refs": [ - "https://twitter.com/JakubKroustek/status/821831437884211201" - ] - }, - "uuid": "d2bc5ec4-1dd1-408a-a6f6-621986657dff", - "value": "Brazilian Globe" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "payment-method": "Phone Number", - "price": "1000 Rubles (15$)", - "refs": [ - "https://www.proofpoint.com/us/threat-insight/post/ransomware-explosion-continues-cryptflle2-brlock-mm-locker-discovered" - ] - }, - "uuid": "889d2296-40d2-49f6-be49-cbdfbcde2246", - "value": "BrLock" - }, - { - "description": "Ransomware no local encryption, browser only", - "uuid": "9769be50-8e0b-4f52-b7f6-98aeac0aaac4", - "value": "Browlock" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".btcware" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "#_HOW_TO_FIX_!.hta" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/845199679340011520" - ] - }, - "uuid": "8d60dec9-d43f-4d52-904f-40fb67e57ef7", - "value": "BTCWare Related to / new version of CryptXXX" - }, - { - "description": "Ransomware no file name change, no extension", - "meta": { - "encryption": "GOST", - "payment-method": "Bitcoin", - "price": "5", - "refs": [ - "http://researchcenter.paloaltonetworks.com/2016/05/unit42-bucbi-ransomware-is-back-with-a-ukrainian-makeover/", - "https://id-ransomware.blogspot.com/2016/05/bucbi-ransomware.html" - ] - }, - "uuid": "3510ce65-80e6-4f80-8cde-bb5ad8a271c6", - "value": "Bucbi" - }, - { - "description": "Ransomware Does not delete Shadow Copies", - "meta": { - "extensions": [ - "(.*).encoded.([A-Z0-9]{9})" - ], - "ransomnotes-filenames": [ - "BUYUNLOCKCODE.txt" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/05/buyunlockcode-ransomware-rsa-1024.html" - ] - }, - "uuid": "289624c4-1d50-4178-9371-aebd95f423f9", - "value": "BuyUnlockCode" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".cry" - ], - "payment-method": "Bitcoin", - "price": "Variable / 0.3 - 1.2 / Double after 4 days and 4 hours", - "ransomnotes-filenames": [ - "!Recovery_[random_chars].html", - "!Recovery_[random_chars].txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/625820/central-security-treatment-organization-ransomware-help-topic-cry-extension/", - "https://id-ransomware.blogspot.com/2016/09/cry-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "629f6986-2c1f-4d0a-b805-e4ef3e2ce634", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "980ea9fa-d29d-4a44-bb87-0c050f8ddeaf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "8ff729d9-aee5-4b85-a59d-3f57e105be40", - "value": "Central Security Treatment Organization" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".cerber", - ".cerber2", - ".cerber3" - ], - "payment-method": "Bitcoin", - "price": "1.24 / 2.48 after 7 days", - "ransomnotes-filenames": [ - "# DECRYPT MY FILES #.html", - "# DECRYPT MY FILES #.txt", - "# DECRYPT MY FILES #.vbs", - "# README.hta", - "_{RAND}_README.jpg", - "_{RAND}_README.hta", - "_HELP_DECRYPT_[A-Z0-9]{4-8}_.jpg", - "_HELP_DECRYPT_[A-Z0-9]{4-8}_.hta", - "_HELP_HELP_HELP_%random%.jpg", - "_HELP_HELP_HELP_%random%.hta", - "_HOW_TO_DECRYPT_[A-Z0-9]{4-8}_.hta", - "_HOW_TO_DECRYPT_[A-Z0-9]{4-8}_.jpg" - ], - "refs": [ - "https://blog.malwarebytes.org/threat-analysis/2016/03/cerber-ransomware-new-but-mature/", - "https://community.rsa.com/community/products/netwitness/blog/2016/11/04/the-evolution-of-cerber-v410", - "https://www.bleepingcomputer.com/news/security/cerber-renames-itself-as-crbr-encryptor-to-be-a-pita/" - ], - "synonyms": [ - "CRBR ENCRYPTOR" - ] - }, - "related": [ - { - "dest-uuid": "79a7203a-6ea5-4c39-abd4-faa20cf8821a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "190edf95-9cd9-4e4a-a228-b716d52a751b", - "value": "Cerber" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".crypt", - "4 random characters, e.g., .PzZs, .MKJL" - ], - "payment-method": "Bitcoin", - "price": "0.939", - "ransomnotes-filenames": [ - "YOUR_FILES_ARE_ENCRYPTED.HTML", - "YOUR_FILES_ARE_ENCRYPTED.TXT", - ".gif" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/chimera-ransomware-decryption-keys-released-by-petya-devs/", - "https://blog.malwarebytes.org/threat-analysis/2015/12/inside-chimera-ransomware-the-first-doxingware-in-wild/" - ], - "synonyms": [ - "Quimera Crypter", - "Pashka" - ] - }, - "uuid": "27b036f0-afa3-4984-95b3-47fa344b1aa7", - "value": "Chimera" - }, - { - "description": "Ransomware Does not encrypt anything", - "meta": { - "payment-method": "Paypal", - "price": "20$", - "refs": [ - "https://twitter.com/JakubKroustek/status/794956809866018816" - ] - }, - "uuid": "af3b3bbb-b54d-49d0-8e58-e9c56762a96b", - "value": "Clock" - }, - { - "description": "Ransomware CryptoGraphic Locker family. Has a GUI. Do not confuse with CrypVault!", - "meta": { - "extensions": [ - ".clf" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "wallpaper.jpg" - ], - "refs": [ - "https://noransom.kaspersky.com/", - "https://id-ransomware.blogspot.com/2016/05/bitcryptor-ransomware-aes-256-1-btc.html" - ] - }, - "uuid": "15941fb1-08f0-4276-a61f-e2a306d6c6b5", - "value": "CoinVault" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".coverton", - ".enigma", - ".czvxce" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "!!!-WARNING-!!!.html", - "!!!-WARNING-!!!.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/paying-the-coverton-ransomware-may-not-get-your-data-back/", - "https://id-ransomware.blogspot.com/2016/04/coverton-ransomware.html" - ] - }, - "uuid": "36450e8c-ff66-4ecf-9c0f-fbfb27a72d63", - "value": "Coverton" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".{CRYPTENDBLACKDC}" - ], - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547" - ] - }, - "uuid": "2c11d679-1fb1-4bd7-9516-9c6f402f3c25", - "value": "Cryaki" - }, - { - "description": "Ransomware", - "meta": { - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547" - ] - }, - "uuid": "93dcd241-f2d6-40f3-aee3-351420046a77", - "value": "Crybola" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "Moves bytes", - "extensions": [ - ".criptiko", - ".criptoko", - ".criptokod", - ".cripttt", - ".aga" - ], - "payment-method": "Email", - "price": "100$", - "ransomnotes-refs": [ - "http://virusinfo.info/showthread.php?t=185396" - ], - "refs": [ - "SHTODELATVAM.txt", - "Instructionaga.txt", - "https://id-ransomware.blogspot.com/2016/06/cryfile-ransomware-100.html" - ] - }, - "uuid": "0d46e21d-8f1c-4355-8205-185fb7e041a7", - "value": "CryFile" - }, - { - "description": "Ransomware Identifies victim locations w/Google Maps API", - "meta": { - "extensions": [ - ".cry" - ], - "payment-method": "Bitcoin", - "price": "Variable / 0.3 - 1.2 / Double after 4 days and 4 hours", - "ransomnotes-filenames": [ - "!Recovery_[random_chars].html", - "!Recovery_[random_chars].txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/the-crylocker-ransomware-communicates-using-udp-and-stores-data-on-imgur-com/", - "https://id-ransomware.blogspot.com/2016/09/cry-ransomware.html" - ], - "synonyms": [ - "Cry", - "CSTO", - "Central Security Treatment Organization" - ] - }, - "related": [ - { - "dest-uuid": "8ff729d9-aee5-4b85-a59d-3f57e105be40", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "980ea9fa-d29d-4a44-bb87-0c050f8ddeaf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "629f6986-2c1f-4d0a-b805-e4ef3e2ce634", - "value": "CryLocker" - }, - { - "description": "Ransomware CryptXXX clone/spinoff", - "meta": { - "encryption": "AES-256", - "payment-method": "Bitcoin", - "price": "Variable / 0.3 - 1.2 / Double after 4 days and 4 hours", - "ransomnotes-filenames": [ - "README.TXT", - "README.HTML", - "README.BMP" - ], - "refs": [ - "http://blog.trendmicro.com/trendlabs-security-intelligence/crypmic-ransomware-wants-to-follow-cryptxxx/", - "https://id-ransomware.blogspot.com/2016/07/crypmic-ransomware-aes-256.html" - ] - }, - "uuid": "82cb7a40-0a78-4414-9afd-028d6b3082ea", - "value": "CrypMIC" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".ENCRYPTED" - ], - "payment-method": "Bitcoin", - "price": "0.1 (45$)", - "ransomnotes-filenames": [ - "READ_THIS_TO_DECRYPT.html" - ], - "refs": [ - "https://github.com/pekeinfo/DecryptCrypren", - "http://www.nyxbone.com/malware/Crypren.html", - "http://www.nyxbone.com/images/articulos/malware/crypren/0.png" - ] - }, - "uuid": "a9f05b4e-6b03-4211-a2bd-6b4432eb3388", - "value": "Crypren" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".crypt38" - ], - "payment-method": "Rubles", - "price": "1000 (15$)", - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/Crypt38Keygen.zip", - "https://blog.fortinet.com/2016/06/17/buggy-russian-ransomware-inadvertently-allows-free-decryption", - "https://id-ransomware.blogspot.com/2016/06/regist-crypt38-ransomware-aes-1000-15.html" - ] - }, - "uuid": "12a96f43-8a8c-410e-aaa3-ba6735276555", - "value": "Crypt38" - }, - { - "description": "Ransomware Does not actually encrypt the files, but simply renames them", - "meta": { - "payment-method": "Bitcoin", - "price": "1", - "refs": [ - "https://twitter.com/jiriatvirlab/status/802554159564062722" - ] - }, - "uuid": "37edc8d7-c939-4a33-9ed5-dafbbc1e5b1e", - "value": "Crypter" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "RSA", - "extensions": [ - ".scl", - "id[_ID]email_xerx@usa.com.scl" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1.5", - "refs": [ - "https://www.proofpoint.com/us/threat-insight/post/ransomware-explosion-continues-cryptflle2-brlock-mm-locker-discovered", - "https://id-ransomware.blogspot.com/2016/06/cryptfile2-ransomware-rsa-email.html" - ], - "synonyms": [ - "Lesli" - ] - }, - "uuid": "5b0dd136-6428-48c8-b2a6-8e926a82dfac", - "value": "CryptFIle2" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crinf" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1.5", - "refs": [ - "https://decrypter.emsisoft.com/", - "https://id-ransomware.blogspot.com/2016/06/cryptfile2-ransomware-rsa-email.html" - ], - "synonyms": [ - "DecryptorMax" - ] - }, - "uuid": "2b0d60c3-6560-49ac-baf0-5f642e8a77de", - "value": "CryptInfinite" - }, - { - "description": "Ransomware sekretzbel0ngt0us.KEY - do not confuse with CryptorBit.", - "meta": { - "encryption": "AES + RSA", - "payment-method": "Bitcoin", - "price": "1 - 2", - "ransomnotes-filenames": [ - "OKSOWATHAPPENDTOYOURFILES.TXT" - ], - "refs": [ - "http://www.pandasecurity.com/mediacenter/panda-security/cryptobit/", - "http://news.softpedia.com/news/new-cryptobit-ransomware-could-be-decryptable-503239.shtml", - "https://id-ransomware.blogspot.com/2016/04/cryptobit-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "681f212a-af1b-4e40-a718-81b0dc46dc52", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "1903ed75-05f7-4019-b0b7-7a8f23f22194", - "value": "CryptoBit" - }, - { - "description": "Ransomware no extension change", - "meta": { - "encryption": "RSA", - "payment-method": "Bitcoin", - "price": "0.9 (500$) - 1.9 (1000$) after 4 days", - "ransomnotes-filenames": [ - "HOW_DECRYPT.TXT", - "HOW_DECRYPT.HTML", - "HOW_DECRYPT.URL" - ], - "refs": [ - "https://decrypter.emsisoft.com/", - "https://id-ransomware.blogspot.com/2016/04/cryptodefense-ransomware.html" - ] - }, - "uuid": "ad9eeff2-91b4-440a-ae74-ab84d3e2075e", - "value": "CryptoDefense" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "0.2", - "refs": [ - "http://blog.talosintel.com/2016/07/ranscam.html", - "https://nakedsecurity.sophos.com/2016/07/13/ransomware-that-demands-money-and-gives-you-back-nothing/", - "https://id-ransomware.blogspot.com/search?q=CryptoFinancial" - ], - "synonyms": [ - "Ranscam" - ] - }, - "related": [ - { - "dest-uuid": "50c92b0b-cae3-41e7-b7d8-dffc2c88ac4b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "383d7ebb-9b08-4874-b5d7-dc02b499c38f", - "value": "CryptoFinancial" - }, - { - "description": "Ransomware Mimics Torrentlocker. Encrypts only 50% of each file up to 5 MB", - "meta": { - "encryption": "AES-256 + RSA-1024", - "extensions": [ - ".frtrss" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "READ IF YOU WANT YOUR FILES BACK.html" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/05/cryptofortress-ransomware-aes-256-1.html" - ] - }, - "related": [ - { - "dest-uuid": "b817ce63-f1c3-49de-bd8b-fd56c3f956c9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ae4aa1ef-4da0-4952-9583-9d47f84edad9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "7f6cd579-b021-4896-80da-fcc07c35c8b2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "26c8b446-305c-4057-83bc-85b09630281e", - "value": "CryptoFortress" - }, - { - "description": "Ransomware Has a GUI. Subvariants: CoinVault BitCryptor", - "meta": { - "extensions": [ - ".clf" - ], - "ransomnotes-filenames": [ - "wallpaper.jpg" - ] - }, - "uuid": "58534bc4-eb96-44f4-bdad-2cc5cfea8c6f", - "value": "CryptoGraphic Locker" - }, - { - "description": "Ransomware RAR's victim's files has a GUI", - "meta": { - "encryption": "AES-256 (RAR implementation)", - "payment-method": "Bitcoin", - "price": "0.33", - "refs": [ - "http://www.bleepingcomputer.com/news/security/cryptohost-decrypted-locks-files-in-a-password-protected-rar-file/", - "https://id-ransomware.blogspot.com/2016/04/cryptohost-ransomware.html" - ], - "synonyms": [ - "Manamecrypt", - "Telograph", - "ROI Locker" - ] - }, - "related": [ - { - "dest-uuid": "54cd671e-b7e4-4dd3-9bfa-dc0ba5105944", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "dba2cf74-16a9-4ed8-8536-6542fda95999", - "value": "CryptoHost" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".crjoker" - ], - "payment-method": "Bitcoin", - "price": "100€", - "ransomnotes-filenames": [ - "README!!!.txt", - "GetYouFiles.txt", - "crjoker.html" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2017/07/cryptojoker-2017-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "10f92054-b028-11e8-a51f-2f82236ac72d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "2fb307a2-8752-4521-8973-75b68703030d", - "value": "CryptoJoker" - }, - { - "description": "Ransomware no longer relevant", - "meta": { - "extensions": [ - ".encrypted", - ".ENC" - ], - "refs": [ - "https://www.fireeye.com/blog/executive-perspective/2014/08/your-locker-of-information-for-cryptolocker-decryption.html", - "https://reaqta.com/2016/04/uncovering-ransomware-distribution-operation-part-2/" - ] - }, - "related": [ - { - "dest-uuid": "c5a783da-9ff3-4427-84c5-428480b21cc7", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b35b1ca2-f99c-4495-97a5-b8f30225cb90", - "value": "CryptoLocker" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Email", - "refs": [ - "https://twitter.com/malwrhunterteam/status/839747940122001408" - ] - }, - "uuid": "8d5e3b1f-e333-4eed-8dec-d74f19d6bcbb", - "value": "CryptoLocker 1.0.0" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "250€", - "refs": [ - "https://twitter.com/malwrhunterteam/status/782890104947867649" - ] - }, - "uuid": "e1412d2a-2a94-4c83-aed0-9e09523514a4", - "value": "CryptoLocker 5.1" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".code", - ".scl", - ".rmd", - ".lesli", - ".rdmk", - ".CRYPTOSHIELD", - ".CRYPTOSHIEL", - ".id_(ID_MACHINE)_email_xoomx@dr.com_.code", - ".id_*_email_zeta@dr.com", - ".id_(ID_MACHINE)_email_anx@dr.com_.scl", - ".email[supl0@post.com]id[\\[[a-z0-9]{16}\\]].lesli", - "*filename*.email[*email*]_id[*id*].rdmk", - ".EMPTY", - ".0000", - ".XZZX", - ".TEST", - ".WORK", - ".SYSTEM", - ".MOLE66", - ".BACKUP", - "[16 uppercase hex].SYS" - ], - "payment-method": "Bitcoin", - "price": "5", - "ransomnotes": [ - "HELP_YOUR_FILES.html (CryptXXX)", - "HELP_YOUR_FILES.txt (CryptoWall 3.0, 4.0)", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\nempty01@techmail.info\n\nempty02@yahooweb.co\n\nempty003@protonmail.com\n\nWe will help You as soon as possible!\n\nDECRYPT-ID-[id] number", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\ny0000@tuta.io\n\ny0000@protonmail.com\n\ny0000z@yandex.com\n\ny0000s@yandex.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nDECRYPT-ID-[id]", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\nxzzx@tuta.io\n\nxzzx1@protonmail.com\n\nxzzx10@yandex.com\n\nxzzx101@yandex.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nDECRYPT-ID-[id] number", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\ntest757@tuta.io\n\ntest757@protonmail.com\n\ntest757xz@yandex.com\n\ntest757xy@yandex.com\n\ntest757@consultant.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nIMPORTANT: DO NOT USE ANY PUBLIC SOFTWARE! IT MAY DAMAGE YOUR DATA FOREVER!\n\nDECRYPT-ID-[id] number", - "Attention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\nworknow@keemail.me\n\nworknow@protonmail.com\n\nworknow8@yandex.com\n\nworknow9@yandex.com\n\nworknow@techie.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nIMPORTANT: DO NOT USE ANY PUBLIC SOFTWARE! IT MAY DAMAGE YOUR DATA FOREVER!\n\nDECRYPT-ID-[id] number", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\nsystemwall@keemail.me\n\nsystemwall@protonmail.com\n\nsystemwall@yandex.com\n\nsystemwall1@yandex.com\n\nemily.w@dr.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nIMPORTANT: DO NOT USE ANY PUBLIC SOFTWARE! IT MAY DAMAGE YOUR DATA FOREVER!\n\nDECRYPT-ID-%s number", - "!!!All your files are encrypted!!!\nWhat to decipher write on mail alpha2018a@aol.com\nDo not move or delete files!!!!\n---- Your ID: 5338f74a-3c20-4ac0-9deb-f3a91818cea7 ----\n!!! You have 3 days otherwise you will lose all your data.!!!", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\nbackuppc@tuta.io\n\nbackuppc@protonmail.com\n\nbackuppc1@protonmail.com\n\nb4ckuppc1@yandex.com\n\nb4ckuppc2@yandex.com\n\nbackuppc1@dr.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nIMPORTANT: DO NOT USE ANY PUBLIC SOFTWARE! IT MAY DAMAGE YOUR DATA FOREVER!\n\n\nDECRYPT-ID-[id] number", - "Hello!\n\nAttention! All Your data was encrypted!\n\nFor specific informartion, please send us an email with Your ID number:\n\nleab@tuta.io\n\nitprocessor@protonmail.com\n\npcambulance1@protonmail.com\n\nleablossom@yandex.com\n\nblossomlea@yandex.com\n\nleablossom@dr.com\n\nPlease send email to all email addresses! We will help You as soon as possible!\n\nIMPORTANT: DO NOT USE ANY PUBLIC SOFTWARE! IT MAY DAMAGE YOUR DATA FOREVER!\n\n\nDECRYPT-ID-[redacted lowercase GUID] number" - ], - "ransomnotes-filenames": [ - "INSTRUCTION RESTORE FILE.TXT", - "# HELP_DECRYPT_YOUR_FILES #.TXT", - "_HELP_INSTRUCTION.TXT", - "C:\\ProgramData\\[random].exe" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/DuFQ4FdWoAMy7Hg.jpg" - ], - "refs": [ - "http://www.nyxbone.com/malware/CryptoMix.html", - "https://www.cert.pl/en/news/single/technical-analysis-of-cryptomixcryptfile2-ransomware/", - "https://twitter.com/JakubKroustek/status/804009831518572544", - "https://www.bleepingcomputer.com/news/security/new-empty-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/0000-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/xzzx-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/test-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/work-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/system-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/mole66-cryptomix-ransomware-variant-released/", - "https://www.bleepingcomputer.com/news/security/new-backup-cryptomix-ransomware-variant-actively-infecting-users/", - "https://twitter.com/demonslay335/status/1072227523755470848", - "https://www.coveware.com/blog/cryptomix-ransomware-exploits-cancer-crowdfunding", - "https://www.bleepingcomputer.com/news/security/cryptomix-ransomware-exploits-sick-children-to-coerce-payments/" - ], - "synonyms": [ - "Zeta" - ] - }, - "related": [ - { - "dest-uuid": "55d5742e-20f5-4c9a-887a-4dbd5b37d921", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "value": "CryptoMix" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "Some Bitcoins", - "refs": [ - "https://twitter.com/malwrhunterteam/status/817672617658347521" - ] - }, - "related": [ - { - "dest-uuid": "2f65f056-6cba-4a5b-9aaf-daf31eb76fc2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "de53f392-8794-43d1-a38b-c0b90c20a3fb", - "value": "CryptoRansomeware" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".crptrgr" - ], - "payment-method": "Bitcoin", - "price": "0.5 (360$)", - "ransomnotes-filenames": [ - "!Where_are_my_files!.html" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/new-ransomware-called-cryptoroger-that-appends-crptrgr-to-encrypted-files/", - "https://id-ransomware.blogspot.com/2016/06/cryptoroger-aes-256-0.html" - ] - }, - "uuid": "b6fe71ba-b0f4-4cc4-b84c-d3d80a37eada", - "value": "CryptoRoger" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".doomed" - ], - "ransomnotes-filenames": [ - "LEER_INMEDIATAMENTE.txt" - ], - "refs": [ - "https://twitter.com/struppigel/status/821992610164277248" - ] - }, - "uuid": "b11563ce-cced-4c8b-a3a1-0c4ff76aa0ef", - "value": "CryptoShadow" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "200$", - "ransomnotes-filenames": [ - "ATTENTION.url" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/617601/cryptoshocker-ransomware-help-and-support-topic-locked-attentionurl/", - "https://id-ransomware.blogspot.com/2016/06/cryptoshocker-ransomware-aes-200.html" - ] - }, - "uuid": "545b4b25-763a-4a5c-8dda-12142c00422c", - "value": "CryptoShocker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".CryptoTorLocker2015!" - ], - "payment-method": "Bitcoin", - "price": "0.5 (100$)", - "ransomnotes-filenames": [ - "HOW TO DECRYPT FILES.txt", - "%Temp%\\.bmp" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/565020/new-cryptotorlocker2015-ransomware-discovered-and-easily-decrypted/", - "https://id-ransomware.blogspot.com/2016/04/cryptotorlocker-ransomware.html" - ] - }, - "uuid": "06ec3640-4b93-4e79-a8ec-e24b3d349dd5", - "value": "CryptoTorLocker2015" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "refs": [ - "http://news.softpedia.com/news/new-open-source-linux-ransomware-shows-infosec-community-divide-508669.shtml" - ] - }, - "uuid": "13fdf55f-46f7-4635-96b8-b4806c78a80c", - "value": "CryptoTrooper" - }, - { - "description": "Ransomware, Infection by Phishing", - "meta": { - "encryption": "RSA", - "payment-method": "Bitcoin", - "price": "1.09 (500$)", - "ransomnotes-filenames": [ - "DECRYPT_INSTRUCTION.HTM", - "DECRYPT_INSTRUCTION.TXT", - "DECRYPT_INSTRUCTION.URL", - "INSTALL_TOR.URL" - ] - }, - "uuid": "5559fbc1-52c6-469c-be97-8f8344765577", - "value": "CryptoWall 1" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "1.09 (500$)", - "ransomnotes-filenames": [ - "HELP_DECRYPT.TXT", - "HELP_DECRYPT.PNG", - "HELP_DECRYPT.URL", - "HELP_DECRYPT.HTML" - ] - }, - "uuid": "f2780d22-4410-4a2f-a1c3-f43807ed1f19", - "value": "CryptoWall 2" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "1.09 (500$)", - "ransomnotes-filenames": [ - "HELP_DECRYPT.TXT", - "HELP_DECRYPT.PNG", - "HELP_DECRYPT.URL", - "HELP_DECRYPT.HTML" - ], - "refs": [ - "https://blogs.technet.microsoft.com/mmpc/2015/01/13/crowti-update-cryptowall-3-0/", - "https://www.virustotal.com/en/file/45317968759d3e37282ceb75149f627d648534c5b4685f6da3966d8f6fca662d/analysis/" - ] - }, - "uuid": "9d35fe47-5f8c-494c-a74f-23a7ac7f44be", - "value": "CryptoWall 3" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "., e.g. ,27p9k967z.x1nep" - ], - "payment-method": "Bitcoin", - "price": "1.09 (500$)", - "ransomnotes-filenames": [ - "HELP_YOUR_FILES.HTML", - "HELP_YOUR_FILES.PNG" - ] - }, - "uuid": "f7c04ce6-dd30-4a94-acd4-9a3125bcb12e", - "value": "CryptoWall 4" - }, - { - "description": "Ransomware Comes with Bedep", - "meta": { - "extensions": [ - ".crypt" - ], - "payment-method": "Bitcoin", - "price": "1.2 (500$) - 2.4", - "ransomnotes-filenames": [ - "de_crypt_readme.bmp", - "de_crypt_readme.txt", - "de_crypt_readme.html", - "[victim_id].html", - "[victim_id].bmp", - "!Recovery_[victim_id].bmp", - "!Recovery_[victim_id].html", - "!Recovery_[victim_id].txt" - ], - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547", - "http://www.bleepingcomputer.com/virus-removal/cryptxxx-ransomware-help-information", - "https://id-ransomware.blogspot.com/2016/04/cryptxxx-ransomware.html" - ], - "synonyms": [ - "CryptProjectXXX" - ] - }, - "related": [ - { - "dest-uuid": "e272d0b5-cdfc-422a-bb78-9214475daec5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "255aac37-e4d2-4eeb-b8de-143f9c2321bd", - "value": "CryptXXX" - }, - { - "description": "Ransomware Locks screen. Ransom note names are an ID. Comes with Bedep.", - "meta": { - "extensions": [ - ".crypt" - ], - "payment-method": "Bitcoin", - "price": "1.2 (500$) - 2.4", - "ransomnotes-filenames": [ - ".txt", - ".html", - ".bmp" - ], - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547", - "https://www.proofpoint.com/us/threat-insight/post/cryptxxx2-ransomware-authors-strike-back-against-free-decryption-tool", - "http://blogs.cisco.com/security/cryptxxx-technical-deep-dive", - "https://id-ransomware.blogspot.com/2016/04/cryptxxx-ransomware.html" - ], - "synonyms": [ - "CryptProjectXXX" - ] - }, - "related": [ - { - "dest-uuid": "255aac37-e4d2-4eeb-b8de-143f9c2321bd", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "e272d0b5-cdfc-422a-bb78-9214475daec5", - "value": "CryptXXX 2.0" - }, - { - "description": "Ransomware Comes with Bedep", - "meta": { - "extensions": [ - ".crypt", - ".cryp1", - ".crypz", - ".cryptz", - "random" - ], - "payment-method": "Bitcoin", - "price": "1.2 (500$) - 2.4", - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547", - "http://www.bleepingcomputer.com/news/security/cryptxxx-updated-to-version-3-0-decryptors-no-longer-work/", - "http://blogs.cisco.com/security/cryptxxx-technical-deep-dive", - "https://id-ransomware.blogspot.com/2016/04/cryptxxx-ransomware.html" - ], - "synonyms": [ - "UltraDeCrypter", - "UltraCrypter" - ] - }, - "uuid": "60a50fe5-53ea-43f0-8a17-e7134f5fc371", - "value": "CryptXXX 3.0" - }, - { - "description": "Ransomware StilerX credential stealing", - "meta": { - "extensions": [ - ".cryp1" - ], - "payment-method": "Bitcoin", - "price": "1.2 (500$) - 2.4", - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547", - "https://www.proofpoint.com/us/threat-insight/post/cryptxxx-ransomware-learns-samba-other-new-tricks-with-version3100", - "https://id-ransomware.blogspot.com/2016/04/cryptxxx-ransomware.html" - ] - }, - "uuid": "3f5a76ea-6b83-443e-b26f-b2b2d02d90e0", - "value": "CryptXXX 3.1" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".cry" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "README_FOR_DECRYPT.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/ctb-faker-ransomware-does-a-poor-job-imitating-ctb-locker/", - "https://id-ransomware.blogspot.com/2016/09/crypy-ransomware.html" - ] - }, - "uuid": "0b0f5f33-1871-461d-8e7e-b5e0ebc82311", - "value": "CryPy" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "RSA-2048", - "extensions": [ - ".ctbl", - ".([a-z]{6,7})" - ], - "payment-method": "Bitcoin", - "price": "0.08686 (50$)", - "ransomnotes-filenames": [ - "AllFilesAreLocked .bmp", - "DecryptAllFiles .txt", - ".html" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/07/ctb-faker-ransomware-008.html" - ], - "synonyms": [ - "Citroni" - ] - }, - "uuid": "6212bf8f-07db-490a-8cef-ac42042076c1", - "value": "CTB-Faker" - }, - { - "description": "Ransomware websites only", - "meta": { - "payment-method": "Bitcoin", - "price": "0.4 - 0.8", - "refs": [ - "https://thisissecurity.net/2016/02/26/a-lockpicking-exercise/", - "https://github.com/eyecatchup/Critroni-php", - "https://id-ransomware.blogspot.com/2016/06/ctb-locker-for-websites-04.html" - ] - }, - "uuid": "555b2c6f-0848-4ac1-9443-e4c20814459a", - "value": "CTB-Locker WEB" - }, - { - "description": "Ransomware Based on my-Little-Ransomware", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".已加密", - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "Your files encrypted by our friends !!! txt" - ], - "ransomnotes-filenames": [ - "你的檔案被我們加密啦!!!.txt" - ], - "refs": [ - "https://github.com/aaaddress1/my-Little-Ransomware/tree/master/decryptoTool", - "https://github.com/aaaddress1/my-Little-Ransomware" - ], - "synonyms": [ - "my-Little-Ransomware" - ] - }, - "uuid": "1a369bbf-6f03-454c-b507-15abe2a8bbb4", - "value": "CuteRansomware" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "payment-method": "Bitcoin", - "price": "1", - "refs": [ - "https://twitter.com/struppigel/status/778871886616862720", - "https://twitter.com/struppigel/status/806758133720698881", - "https://id-ransomware.blogspot.com/2016/09/cyber-splitter-vbs-ransomware.html" - ], - "synonyms": [ - "CyberSplitter" - ] - }, - "related": [ - { - "dest-uuid": "8bde6075-8c5b-4ff1-be9a-4e2b1d3419aa", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "587589df-ee42-43f4-9480-c65d6e1d7e0f", - "value": "Cyber SpLiTTer Vbs" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "1.5", - "ransomnotes-filenames": [ - "READ_IT.txt" - ], - "refs": [ - "https://twitter.com/JaromirHorejsi/status/815555258478981121" - ] - }, - "uuid": "0f074c07-613d-43cb-bd5f-37c747d39fe2", - "value": "Death Bitches" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".html" - ], - "refs": [ - "http://www.malwareremovalguides.info/decrypt-files-with-decrypt_mblblock-exe-decrypt-protect/" - ] - }, - "uuid": "c80c78ae-fc05-44cf-8b47-4d50c103ca70", - "value": "DeCrypt Protect" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".ded" - ], - "payment-method": "Bitcoin", - "price": "2", - "refs": [ - "http://www.bleepingcomputer.com/forums/t/617395/dedcryptor-ded-help-support-topic/", - "http://www.nyxbone.com/malware/DEDCryptor.html", - "https://id-ransomware.blogspot.com/2016/06/dedcryptor-ransomware-aes-256rsa-2.html" - ] - }, - "uuid": "496b6c3c-771a-46cd-8e41-ce7c4168ae20", - "value": "DEDCryptor" - }, - { - "description": "Ransomware only encrypts .jpg files", - "meta": { - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "HELP_YOUR_FILES.txt" - ], - "refs": [ - "https://twitter.com/struppigel/status/798573300779745281", - "https://id-ransomware.blogspot.com/2017/10/cryptodemo-ransomware.html" - ], - "synonyms": [ - "CryptoDemo" - ] - }, - "uuid": "b314d86f-92bb-4be3-b32a-19d6f8eb55d4", - "value": "Demo" - }, - { - "description": "Ransomware - Based on Detox: Calipso, We are all Pokemons, Nullbyte", - "meta": { - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "2 - 3", - "refs": [ - "http://www.bleepingcomputer.com/news/security/new-detoxcrypto-ransomware-pretends-to-be-pokemongo-or-uploads-a-picture-of-your-screen/", - "https://id-ransomware.blogspot.com/2016/08/detoxcrypto-ransomware.html" - ] - }, - "uuid": "be094d75-eba8-4ff3-91f1-f8cde687e5ed", - "value": "DetoxCrypto" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "0.05", - "ransomnotes": [ - "Digisom Readme0.txt (0 to 9)" - ], - "refs": [ - "https://twitter.com/PolarToffee/status/829727052316160000" - ] - }, - "uuid": "c5b2a0bc-352f-481f-8c35-d378754793c0", - "value": "Digisom" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "No ransom", - "refs": [ - "https://twitter.com/demonslay335/status/752586334527709184", - "https://id-ransomware.blogspot.com/2016/07/revoyem-dirtydecrypt-ransomware-doc.html" - ] - }, - "uuid": "5ad8a530-3ab9-48b1-9a75-e1e97b3f77ec", - "value": "DirtyDecrypt" - }, - { - "description": "Ransomware no extension change Encrypted files have prefix: Version 1: ABCXYZ11 - Version 2: !DMALOCK - Version 3: !DMALOCK3.0 - Version 4: !DMALOCK4.0", - "meta": { - "encryption": "AES-256 in ECB mode, Version 2-4 also RSA", - "payment-method": "Bitcoin", - "price": "1 - 2 - 4", - "ransomnotes-filenames": [ - "cryptinfo.txt", - "decrypting.txt", - "start.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/", - "https://github.com/hasherezade/dma_unlocker", - "https://drive.google.com/drive/folders/0Bzb5kQFOXkiSMm94QzdyM3hCdDg", - "https://blog.malwarebytes.org/threat-analysis/2016/02/dma-locker-a-new-ransomware-but-no-reason-to-panic/" - ] - }, - "uuid": "407ebc7c-5b05-488f-862f-b2bf6c562372", - "value": "DMALocker" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256 + XPTLOCK5.0", - "payment-method": "Bitcoin", - "price": "1 - 2 (440$)", - "refs": [ - "https://drive.google.com/drive/folders/0Bzb5kQFOXkiSMm94QzdyM3hCdDg", - "https://blog.malwarebytes.org/threat-analysis/2016/02/dma-locker-strikes-back/" - ] - }, - "uuid": "ba39be57-c138-48d5-b46b-d996ff899ffa", - "value": "DMALocker 3.0" - }, - { - "description": "Ransomware Code to decrypt: 83KYG9NW-3K39V-2T3HJ-93F3Q-GT", - "meta": { - "extensions": [ - ".fucked" - ], - "payment-method": "Bitcoin", - "price": "0.5 (864$)", - "refs": [ - "https://twitter.com/BleepinComputer/status/822500056511213568" - ] - }, - "uuid": "45cae006-5d14-4c95-bb5b-dcf5555d7c78", - "value": "DNRansomware" - }, - { - "description": "Ransomware Based on Hidden Tear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".domino" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "README_TO_RECURE_YOUR_FILES.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/Domino.html", - "http://www.bleepingcomputer.com/news/security/the-curious-case-of-the-domino-ransomware-a-windows-crack-and-a-cow/", - "https://id-ransomware.blogspot.com/2016/08/domino-ransomware.html" - ] - }, - "uuid": "7cb20800-2033-49a4-bdf8-a7da5a24f7f1", - "value": "Domino" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".id-7ES642406.cry", - ".Do_not_change_the_filename" - ], - "payment-method": "Email", - "price": "250$", - "ransomnotes-filenames": [ - "HOW TO DECODE FILES!!!.txt", - "КАК РАСШИФРОВАТЬ ФАЙЛЫ!!!.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/forums/t/643330/donotchange-ransomware-id-7es642406cry-do-not-change-the-file-namecryp/", - "https://id-ransomware.blogspot.com/2017/03/donotchange-ransomware.html" - ] - }, - "uuid": "2e6f4fa6-5fdf-4d69-b764-063d88ba1dd0", - "value": "DoNotChange" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".dCrypt" - ], - "refs": [ - "https://twitter.com/struppigel/status/794108322932785158" - ] - }, - "uuid": "55446b3a-fdc7-4c75-918a-2d9fb5cdf3ff", - "value": "DummyLocker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".dxxd" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "ReadMe.TxT" - ], - "refs": [ - "https://www.bleepingcomputer.com/forums/t/627831/dxxd-ransomware-dxxd-help-support-readmetxt/", - "https://www.bleepingcomputer.com/news/security/the-dxxd-ransomware-displays-legal-notice-before-users-login/", - "https://id-ransomware.blogspot.com/2016/09/dxxd-ransomware.html" - ] - }, - "uuid": "57108b9e-5af8-4797-9924-e424cb5e9903", - "value": "DXXD" - }, - { - "description": "Ransomware Open sourced C#", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Download Decrypter", - "refs": [ - "http://www.utkusen.com/blog/dealing-with-script-kiddies-cryptear-b-incident.html", - "https://id-ransomware.blogspot.com/2016/06/hiddentear-2.html" - ], - "synonyms": [ - "Cryptear", - "EDA2", - "Hidden Tear" - ] - }, - "related": [ - { - "dest-uuid": "24fe5fef-6325-4c21-9c35-a0ecd185e254", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b96be762-56a0-4407-be04-fcba76c1ff29", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "254f4f67-d850-4dc5-8ddb-2e955ddea287", - "value": "HiddenTear" - }, - { - "description": "Ransomware Based on Hidden Tear", - "meta": { - "extensions": [ - ".isis", - ".locked" - ], - "payment-method": "Download Decryter", - "ransomnotes-filenames": [ - "README.txt" - ], - "refs": [ - "http://www.filedropper.com/decrypter_1", - "https://twitter.com/JakubKroustek/status/747031171347910656", - "https://id-ransomware.blogspot.com/2016/06/hiddentear-2.html" - ], - "synonyms": [ - "EduCrypter" - ] - }, - "uuid": "826a341a-c329-4e1e-bc9f-5d44c8317557", - "value": "EduCrypt" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crypted" - ], - "payment-method": "Bitcoin", - "price": "0.25 (320$)", - "refs": [ - "https://twitter.com/BroadAnalysis/status/845688819533930497", - "https://twitter.com/malwrhunterteam/status/845652520202616832" - ] - }, - "uuid": "0a24ea0d-3f8a-428a-8b77-ef5281c1ee05", - "value": "EiTest" - }, - { - "description": "Ransomware Has a GUI", - "meta": { - "extensions": [ - ".ha3" - ], - "payment-method": "Email", - "price": "450$ - 1000$", - "ransomnotes-filenames": [ - "qwer.html", - "qwer2.html", - "locked.bmp" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/07/el-polocker-ransomware-aes-450-aud.html" - ], - "synonyms": [ - "Los Pollos Hermanos" - ] - }, - "uuid": "63d9cb32-a1b9-46c3-818a-df16d8b9e46a", - "value": "El-Polocker" - }, - { - "description": "Ransomware Coded in GO", - "meta": { - "ransomnotes-filenames": [ - "Instructions.html" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-14-2016-exotic-lockydump-comrade-and-more/", - "http://vms.drweb.ru/virus/?_is=1&i=8747343" - ], - "synonyms": [ - "Trojan.Encoder.6491" - ] - }, - "related": [ - { - "dest-uuid": "a57a8bc3-8c33-43e8-b237-25edcd5f532a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "f855609e-b7ab-41e8-aafa-62016f8f4e1a", - "value": "Encoder.xxxx" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".enc" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "How to recover.enc" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/11/encryptojjs-ransomware.html" - ] - }, - "uuid": "3e5deef2-bace-40bc-beb1-5d9009233667", - "value": "encryptoJJS" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".enigma", - ".1txt" - ], - "payment-method": "WebSite (onion)", - "ransomnotes-filenames": [ - "enigma.hta", - "enigma_encr.txt", - "enigma_info.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/the-enigma-ransomware-targets-russian-speaking-users/", - "https://id-ransomware.blogspot.com/2016/05/enigma-ransomware-aes-128-0.html" - ] - }, - "uuid": "1b24d240-df72-4388-946b-efa07a9447bb", - "value": "Enigma" - }, - { - "description": "Ransomware Based on RemindMe", - "meta": { - "payment-method": "Bitcoin - Email", - "refs": [ - "https://twitter.com/malwrhunterteam/status/839022018230112256" - ] - }, - "uuid": "198891fb-26a4-455a-9719-4130bedba103", - "value": "Enjey" - }, - { - "description": "Ransomware Target Linux O.S.", - "meta": { - "payment-method": "Bitcoin", - "price": "2", - "refs": [ - "http://www.bleepingcomputer.com/news/security/new-fairware-ransomware-targeting-linux-computers/" - ] - }, - "uuid": "6771b42f-1d95-4b2e-bbb5-9ab703bbaa9d", - "value": "Fairware" - }, - { - "description": "Ransomware Based on Hidden Tear", - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "1.50520802", - "ransomnotes-filenames": [ - "READ ME FOR DECRYPT.txt" - ], - "refs": [ - "https://blog.fortinet.com/post/fakben-team-ransomware-uses-open-source-hidden-tear-code", - "https://id-ransomware.blogspot.com/2016/07/fakben-team-ransomware-aes-256-1505.html" - ] - }, - "uuid": "c308346a-2746-4900-8149-464a09086b55", - "value": "Fakben" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".cryptolocker" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://twitter.com/PolarToffee/status/812312402779836416" - ] - }, - "uuid": "abddc01f-7d76-47d4-985d-ea6d16acccb1", - "value": "FakeCryptoLocker" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".fantom", - ".comrade" - ], - "payment-method": "Email", - "ransomnotes": [ - "RESTORE-FILES![id]" - ], - "ransomnotes-filenames": [ - "DECRYPT_YOUR_FILES.HTML" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/fantom-ransomware-encrypts-your-files-while-pretending-to-be-windows-update/" - ], - "synonyms": [ - "Comrad Circle" - ] - }, - "uuid": "35be87a5-b498-4693-8b8d-8b17864ac088", - "value": "Fantom" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".FenixIloveyou!!" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "Help to decrypt.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/fenixlocker", - "https://twitter.com/fwosar/status/777197255057084416", - "https://id-ransomware.blogspot.com/2016/09/fenixlocker-ransomware.html" - ] - }, - "uuid": "f9f54046-ed5d-4353-8b81-d92b51f596b4", - "value": "FenixLocker" - }, - { - "description": "Ransomware RaaS", - "meta": { - "payment-method": "Bitcoin", - "price": "1", - "refs": [ - "https://twitter.com/rommeljoven17/status/846973265650335744", - "https://id-ransomware.blogspot.com/2017/03/filefrozr-ransomware.html" - ], - "synonyms": [ - "FileFrozr" - ] - }, - "uuid": "2a50f476-7355-4d58-b0ce-4235b2546c90", - "value": "FILE FROZR" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".ENCR" - ], - "payment-method": "Bitcoin", - "price": "0.09 (100$ with discount price) - 150$", - "refs": [ - "https://twitter.com/jiriatvirlab/status/836616468775251968" - ] - }, - "uuid": "b92bc550-7edb-4f8f-96fc-cf47d437df32", - "value": "FileLocker" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".firecrypt" - ], - "payment-method": "Bitcoin", - "price": "500$", - "ransomnotes-filenames": [ - "[random_chars]-READ_ME.html" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/firecrypt-ransomware-comes-with-a-ddos-component/", - "https://id-ransomware.blogspot.com/2017/01/bleedgreen-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "c4346ed0-1d74-4476-a78c-299bce0409bd", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "721ba430-fd28-454c-8512-24339ef2235f", - "value": "FireCrypt" - }, - { - "description": "Ransomware Based on EDA2 / HiddenTear", - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://twitter.com/malwrhunterteam/status/773771485643149312", - "https://id-ransomware.blogspot.com/2016/09/flyper-ransomware.html" - ] - }, - "uuid": "1a110f7e-8820-4a9a-86c0-db4056f0b911", - "value": "Flyper" - }, - { - "description": "Ransomware contact email safefiles32@mail.ru also as prefix in encrypted file contents", - "meta": { - "payment-method": "Email", - "ransomnotes-filenames": [ - "help-file-decrypt.enc", - "/pronk.txt" - ] - }, - "uuid": "3d75cb84-2f14-408d-95bd-f1316bf854e6", - "value": "Fonco" - }, - { - "description": "Ransomware", - "meta": { - "refs": [ - "https://twitter.com/struppigel/status/842302481774321664" - ] - }, - "uuid": "2db3aafb-b219-4b52-8dfe-ce41416ebeab", - "value": "FortuneCookie" - }, - { - "description": "Ransomware Unlock code is: adam or adamdude9", - "meta": { - "extensions": [ - ".madebyadam" - ], - "payment-method": "Playstore Card (Gift)", - "price": "25£ or 30$", - "refs": [ - "https://twitter.com/BleepinComputer/status/812135608374226944", - "https://id-ransomware.blogspot.com/2016/12/roga-ransomware.html" - ], - "synonyms": [ - "Roga" - ] - }, - "related": [ - { - "dest-uuid": "cd1eb48e-070b-418e-8d83-4644a388f8ae", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "175ebcc0-d74f-49b2-9226-c660ca1fe2e8", - "value": "Free-Freedom" - }, - { - "description": "Ransomware Based on EDA2 and RemindMe", - "meta": { - "extensions": [ - ".fs0ciety", - ".dll" - ], - "payment-method": "No Ransom - No Descrypter", - "ransomnotes-filenames": [ - "fs0ciety.html", - "DECRYPT_YOUR_FILES.HTML" - ], - "refs": [ - "https://www.bleepingcomputer.com/forums/t/628199/fs0ciety-locker-ransomware-help-support-fs0cietyhtml/", - "http://www.bleepingcomputer.com/news/security/new-fsociety-ransomware-pays-homage-to-mr-robot/", - "https://twitter.com/siri_urz/status/795969998707720193", - "https://id-ransomware.blogspot.com/2016/08/fsociety-ransomware.html" - ] - }, - "uuid": "d1e7c0d9-3c96-41b7-a4a2-7eaef64d7b0f", - "value": "FSociety" - }, - { - "description": "Ransomware", - "meta": { - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547" - ] - }, - "uuid": "291997b1-72b6-43ea-9365-b4d55eddca71", - "value": "Fury" - }, - { - "description": "Ransomware Based on Hidden Tear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".Z81928819" - ], - "payment-method": "Bitcoin", - "price": "2", - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/GhostCryptDecrypter.zip", - "http://www.bleepingcomputer.com/forums/t/614197/ghostcrypt-z81928819-help-support-topic-read-this-filetxt/", - "https://id-ransomware.blogspot.com/2016/05/ghostcrypt-ransomware-aes-256-2-bitcoins.html" - ] - }, - "uuid": "3b681f76-b0e4-4ba7-a113-5dd87d6ee53b", - "value": "GhostCrypt" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Email", - "refs": [ - "https://twitter.com/ni_fi_70/status/796353782699425792" - ] - }, - "uuid": "c6419971-47f8-4c80-a685-77292ff30fa7", - "value": "Gingerbread" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "Blowfish", - "extensions": [ - ".purge" - ], - "payment-method": "Bitcoin", - "price": "250$", - "ransomnotes-filenames": [ - "How to restore files.hta" - ], - "refs": [ - "https://success.trendmicro.com/portal_kb_articledetail?solutionid=1114221", - "http://www.bleepingcomputer.com/news/security/the-globe-ransomware-wants-to-purge-your-files/", - "https://id-ransomware.blogspot.com/2017/07/purge-kind-ransomware.html" - ], - "synonyms": [ - "Purge" - ] - }, - "uuid": "b247b6e5-f51b-4bb5-8f5a-1628843abe99", - "value": "Globe v1" - }, - { - "description": "Ransomware Only encrypts DE or NL country. Variants, from old to latest: Zyklon Locker, WildFire locker, Hades Locker", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked", - ".locked, e.g., bill.!ID!8MMnF!ID!.locked" - ], - "payment-method": "Bitcoin", - "price": "0.5(190 - 250 $)", - "ransomnotes-filenames": [ - "UNLOCK_FILES_INSTRUCTIONS.html", - "UNLOCK_FILES_INSTRUCTIONS.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/611342/gnl-locker-support-and-help-topic-locked-and-unlock-files-instructionshtml/", - "http://id-ransomware.blogspot.ru/2016/05/gnl-locker-ransomware-gnl-locker-ip.html" - ] - }, - "related": [ - { - "dest-uuid": "78ef77ac-a570-4fb9-af80-d04c09dff9ab", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "721e9af0-8a60-4b9e-9137-c23e86d75722", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "390abe30-8b9e-439e-a6d3-2ee978f05fba", - "value": "GNL Locker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crypt", - "!___[EMAILADDRESS]_.crypt" - ], - "payment-method": "Email", - "refs": [ - "https://decrypter.emsisoft.com/", - "http://id-ransomware.blogspot.com/2016/05/gomasom-ransonware.html" - ] - }, - "uuid": "70b85861-f419-4ad5-9aa6-254db292e043", - "value": "Gomasom" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "500 $", - "ransomnotes-filenames": [ - "Your files have been crypted.html" - ], - "refs": [ - "http://blog.trendmicro.com/trendlabs-security-intelligence/angler-shift-ek-landscape-new-crytpo-ransomware-activity/" - ] - }, - "uuid": "3229a370-7a09-4b93-ad89-9555a847b1dd", - "value": "Goopic" - }, - { - "description": "Ransomware OS X ransomware (PoC)", - "meta": { - "date": "mars 2021" - }, - "uuid": "ec461b8a-5390-4304-9d2a-a20c7ed6a9db", - "value": "Gopher" - }, - { - "description": "Ransomware Jigsaw Ransomware variant", - "meta": { - "extensions": [ - ".versiegelt", - ".encrypted", - ".payrmts", - ".locked", - ".Locked" - ], - "payment-method": "Bitcoin", - "price": "0.33 - 0.5", - "refs": [ - "https://twitter.com/demonslay335/status/806878803507101696", - "http://id-ransomware.blogspot.com/2016/12/hackedlocker-ransomware.html" - ] - }, - "uuid": "7f2df0cd-5962-4687-90a2-a49eab2b12bc", - "value": "Hacked" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "3DES, AES-128, AES-192, AES-256, DES, RC2, RC4", - "payment-method": "MoneyPak", - "price": "0.5", - "refs": [ - "https://twitter.com/malwrhunterteam/status/847114064224497666", - "http://id-ransomware.blogspot.com/2017/03/happydayzz-blackjocker-ransomware.html" - ] - }, - "uuid": "e71c76f3-8274-4ec5-ac11-ac8b8286d069", - "value": "HappyDayzz" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".html" - ], - "payment-method": "MoneyPak", - "price": "100 $", - "refs": [ - "https://decrypter.emsisoft.com/" - ] - }, - "uuid": "5cadd11c-002a-4062-bafd-aadb7d740f59", - "value": "Harasom" - }, - { - "description": "Ransomware Uses https://diskcryptor.net for full disk encryption", - "meta": { - "encryption": "Custom (net shares), XTS-AES (disk)", - "payment-method": "Email", - "refs": [ - "https://www.linkedin.com/pulse/mamba-new-full-disk-encryption-ransomware-family-member-marinho", - "blog.trendmicro.com/trendlabs-security-intelligence/bksod-by-ransomware-hddcryptor-uses-commercial-tools-to-encrypt-network-shares-and-lock-hdds/", - "http://id-ransomware.blogspot.com/2016/09/hddcryptor-ransomware-mbr.html" - ], - "synonyms": [ - "Mamba" - ] - }, - "related": [ - { - "dest-uuid": "df320366-7970-4af0-b1f4-9f9492dede53", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "95be4cd8-1d98-484f-a328-a5917a05e3c8", - "value": "HDDCryptor" - }, - { - "description": "Ransomware File marker: \"Heimdall---\"", - "meta": { - "encryption": "AES-128-CBC", - "payment-method": "Bitcoin", - "refs": [ - "https://www.bleepingcomputer.com/news/security/heimdall-open-source-php-ransomware-targets-web-servers/", - "https://id-ransomware.blogspot.com/2016/11/heimdall-ransomware.html" - ] - }, - "uuid": "c6d6ddf0-2afa-4cca-8982-ba2a7c0441ae", - "value": "Heimdall" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".XXX" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "help_dcfile.txt" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/09/helpdcfile-ransomware.html" - ] - }, - "uuid": "2fdc6daa-6b6b-41b9-9a25-1030101478c3", - "value": "Help_dcfile" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".herbst" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "refs": [ - "https://blog.fortinet.com/2016/06/03/cooking-up-autumn-herbst-ransomware", - "https://id-ransomware.blogspot.com/2016/06/herbst-autumn-ransomware-aes-256-01.html" - ] - }, - "related": [ - { - "dest-uuid": "ca8482d9-657b-49fe-8345-6ed962a9735a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "6489895b-0213-4564-9cfc-777df58d84c9", - "value": "Herbst" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".cry" - ], - "payment-method": "Bitcoin", - "price": "0.77756467", - "refs": [ - "http://www.nyxbone.com/malware/hibuddy.html", - "http://id-ransomware.blogspot.ru/2016/05/hi-buddy-ransomware-aes-256-0.html" - ] - }, - "uuid": "a0d6563d-1e98-4e49-9151-39fbeb09ef76", - "value": "Hi Buddy!" - }, - { - "description": "Ransomware Deletes files", - "meta": { - "extensions": [ - "removes extensions" - ], - "payment-method": "Vodafone card", - "price": "25 €", - "refs": [ - "http://www.bleepingcomputer.com/news/security/development-version-of-the-hitler-ransomware-discovered/", - "https://twitter.com/jiriatvirlab/status/825310545800740864", - "http://id-ransomware.blogspot.com/2016/08/hitler-ransomware.html" - ] - }, - "uuid": "8807752b-bd26-45a7-ba34-c8ddd8e5781d", - "value": "Hitler" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - "(encrypted)" - ], - "payment-method": "Link (onion)", - "refs": [ - "http://www.bleepingcomputer.com/news/security/new-python-ransomware-called-holycrypt-discovered/", - "https://id-ransomware.blogspot.com/2016/07/holycrypt-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "d3337bec-fd4e-11e8-a3ad-e799cc59c59c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "c71819a4-f6ce-4265-b0cd-24a98d84321c", - "value": "HolyCrypt" - }, - { - "description": "Ransomware Includes a feature to disable the victim's windows firewall Modified in-dev HiddenTear", - "meta": { - "payment-method": "Bitcoin", - "price": "vary", - "refs": [ - "https://twitter.com/BleepinComputer/status/803288396814839808" - ] - }, - "uuid": "728aecfc-9b99-478f-a0a3-8c0fb6896353", - "value": "HTCryptor" - }, - { - "description": "Ransomware CrypBoss Family", - "meta": { - "extensions": [ - "hydracrypt_ID_[\\w]{8}" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "README_DECRYPT_HYRDA_ID_[ID number].txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/", - "http://www.malware-traffic-analysis.net/2016/02/03/index2.html", - "https://id-ransomware.blogspot.com/2016/06/hydracrypt-ransomware-aes-256-cbc-rsa.html" - ] - }, - "uuid": "335c3ab6-8f2c-458c-92a3-2f3a09a6064c", - "value": "HydraCrypt" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crime" - ], - "payment-method": "Website onion", - "refs": [ - "https://twitter.com/BleepinComputer/status/817085367144873985" - ] - }, - "uuid": "68e90fa4-ea66-4159-b454-5f48fdae3d89", - "value": "iLock" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crime" - ], - "payment-method": "Bitcoin", - "price": "300 $" - }, - "uuid": "cb374ee8-76c0-4db8-9026-a57a51d9a0a1", - "value": "iLockLight" - }, - { - "description": "Ransomware CryptoTorLocker2015 variant", - "meta": { - "extensions": [ - "<6 random characters>" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "ransomnotes-filenames": [ - "%Temp%\\.bmp" - ], - "refs": [ - "http://download.bleepingcomputer.com/Nathan/StopPirates_Decrypter.exe" - ] - }, - "uuid": "a66fbb1e-ba59-48c1-aac8-8678b4a98dc1", - "value": "International Police Association" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".Locked" - ], - "payment-method": "Bitcoin", - "price": "0.15", - "refs": [ - "https://twitter.com/demonslay335/status/796134264744083460", - "http://id-ransomware.blogspot.com/2016/11/iransom-ransomware.html" - ] - }, - "uuid": "4514ecd4-850d-446f-82cb-0668d2c94ffa", - "value": "iRansom" - }, - { - "description": "Ransomware Prepends filenames", - "meta": { - "extensions": [ - "!ENC" - ], - "payment-method": "Bitcoin", - "price": "50 $", - "ransomnotes-filenames": [ - "Important_Read_Me.html" - ], - "refs": [ - "https://twitter.com/JakubKroustek/status/757873976047697920" - ] - }, - "uuid": "25a086aa-e25c-4190-a848-69d9f46fd8ab", - "value": "JagerDecryptor" - }, - { - "description": "Ransomware Windows, Linux. Campaign stopped. Actor claimed he deleted the master key.", - "meta": { - "encryption": "RC6 (files), RSA 2048 (RC6 key)", - "payment-method": "Bitcoin", - "price": "0.046627", - "ransomnotes-filenames": [ - "readme_liesmich_encryptor_raas.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/RaaS.html", - "http://blog.trendmicro.com/trendlabs-security-intelligence/the-rise-and-fall-of-encryptor-raas/" - ], - "synonyms": [ - "Encryptor RaaS", - "Sarento" - ] - }, - "uuid": "50014fe7-5efd-4639-82ef-30d36f4d2918", - "value": "Jeiphoos" - }, - { - "description": "Ransomware Same codebase as DNRansomware Lock screen password is M3VZ>5BwGGVH", - "meta": { - "extensions": [ - ".killedXXX" - ], - "payment-method": "PaySafeCard", - "price": "0.1", - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/DoNotOpenDecrypter.zip", - "https://twitter.com/BleepinComputer/status/822509105487245317" - ] - }, - "uuid": "fedd7285-d4bd-4411-985e-087954cee96d", - "value": "Jhon Woddy" - }, - { - "description": "Ransomware Has a GUI", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".btc", - ".kkk", - ".fun", - ".gws", - ".porno", - ".payransom", - ".payms", - ".paymst", - ".AFD", - ".paybtcs", - ".epic", - ".xyz", - ".encrypted", - ".hush", - ".paytounlock", - ".uk-dealer@sigaint.org", - ".gefickt", - ".nemo-hacks.at.sigaint.org", - ".LolSec" - ], - "payment-method": "PaySafeCard", - "price": "0.4 (150 $)", - "refs": [ - "http://www.bleepingcomputer.com/news/security/jigsaw-ransomware-decrypted-will-delete-your-files-until-you-pay-the-ransom/", - "https://www.helpnetsecurity.com/2016/04/20/jigsaw-crypto-ransomware/", - "https://twitter.com/demonslay335/status/795819556166139905", - "https://id-ransomware.blogspot.com/2016/04/jigsaw-ransomware.html" - ], - "synonyms": [ - "CryptoHitMan", - "Jigsaw Original" - ] - }, - "related": [ - { - "dest-uuid": "910c3fd2-56e5-4f1d-8df0-2aa0b293b7d9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "1e3384ae-4b48-4c96-b7c2-bc1cc1eda203", - "value": "Jigsaw" - }, - { - "description": "Ransomware Based on HiddenTear, but uses TripleDES, decrypter is PoC", - "meta": { - "encryption": "TripleDES", - "extensions": [ - ".locked", - ".css" - ], - "payment-method": "PaySafeCard", - "price": "300 €", - "ransomnotes-filenames": [ - "Comment débloquer mes fichiers.txt", - "Readme.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/jobcrypter.html", - "http://forum.malekal.com/jobcrypter-geniesanstravaille-extension-locked-crypto-ransomware-t54381.html", - "https://twitter.com/malwrhunterteam/status/828914052973858816", - "http://id-ransomware.blogspot.com/2016/05/jobcrypter-ransomware.html" - ], - "synonyms": [ - "JobCrypter" - ] - }, - "uuid": "7c9a273b-1534-4a13-b201-b7a782b6c32a", - "value": "Job Crypter" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Email", - "refs": [ - "http://id-ransomware.blogspot.com/2016/04/johnycryptor-ransomware.html" - ] - }, - "uuid": "5af5be3e-549f-4485-8c2e-1459d4e5c7d7", - "value": "JohnyCryptor" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "rubles", - "price": "6 000", - "ransomnotes-filenames": [ - "How Decrypt Files.txt" - ], - "refs": [ - "https://safezone.cc/resources/kawaii-decryptor.195/", - "http://id-ransomware.blogspot.com/2016/09/kawaiilocker-ransomware.html" - ] - }, - "uuid": "b6d0ea4d-4e55-4b42-9d60-485d605d6c49", - "value": "KawaiiLocker" - }, - { - "description": "Ransomware OS X Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "1", - "refs": [ - "http://news.drweb.com/show/?i=9877&lng=en&c=5", - "http://www.welivesecurity.com/2016/03/07/new-mac-ransomware-appears-keranger-spread-via-transmission-app/", - "https://id-ransomware.blogspot.com/2016/03/keranger-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "01643bc9-bd61-42e8-b9f1-5fbf83dcd786", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "63292b32-9867-4fb2-9e59-d4983d4fd5d1", - "value": "KeRanger" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "keybtc@inbox_com" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "DECRYPT_YOUR_FILES.txt", - "READ.txt", - "readme.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/" - ] - }, - "uuid": "3964e617-dde5-4c95-b4a0-e7c19c6e7d7f", - "value": "KeyBTC" - }, - { - "description": "Ransomware via remote attacker. tuyuljahat@hotmail.com contact address", - "meta": { - "payment-method": "Bitcoin", - "price": "1.5 (500 $)", - "ransomnotes-filenames": [ - "how_decrypt.gif", - "how_decrypt.html" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/559463/keyholder-ransomware-support-and-help-topic-how-decryptgifhow-decrypthtml", - "https://id-ransomware.blogspot.com/2016/06/keyholder-ransomware-xor-cfb-cipher.html" - ] - }, - "uuid": "66eda328-9408-4e98-ad27-572fd6b2acd8", - "value": "KEYHolder" - }, - { - "description": "Ransomware Possibly Portuguese dev", - "meta": { - "extensions": [ - ".rip" - ], - "payment-method": "Bitcoin", - "refs": [ - "https://twitter.com/malwrhunterteam/status/782232299840634881", - "http://id-ransomware.blogspot.com/2016/10/killerlocker-ransomware.html" - ] - }, - "uuid": "ea8e7350-f243-4ef7-bc31-4648df8a4d96", - "value": "KillerLocker" - }, - { - "description": "Ransomware websites only", - "meta": { - "encryption": "AES", - "extensions": [ - ".kimcilware", - ".locked" - ], - "payment-method": "Dollars", - "price": "140 - 415", - "refs": [ - "https://blog.fortinet.com/post/kimcilware-ransomware-how-to-decrypt-encrypted-files-and-who-is-behind-it", - "http://www.bleepingcomputer.com/news/security/the-kimcilware-ransomware-targets-web-sites-running-the-magento-platform/", - "http://id-ransomware.blogspot.com/2016/04/kimcilware-ransomware.html" - ] - }, - "uuid": "950e2514-8a7e-4fdb-a3ad-5679f6342e5d", - "value": "KimcilWare" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".암호화됨" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "ReadMe.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/koreanRansom.html", - "http://id-ransomware.blogspot.com/2016/08/korean-ransomware.html" - ] - }, - "uuid": "4febffe0-3837-41d7-b95f-e26d126275e4", - "value": "Korean" - }, - { - "description": "Ransomware Potential Kit selectedkozy.jozy@yahoo.com kozy.jozy@yahoo.com unlock92@india.com", - "meta": { - "encryption": "RSA-2048", - "extensions": [ - ".31392E30362E32303136_[ID-KEY]_LSBJ1", - ".([0-9A-Z]{20})_([0-9]{2})_([A-Z0-9]{4,5})" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "w.jpg" - ], - "refs": [ - "http://www.nyxbone.com/malware/KozyJozy.html", - "http://www.bleepingcomputer.com/forums/t/617802/kozyjozy-ransomware-help-support-wjpg-31392e30362e32303136-num-lsbj1/", - "https://id-ransomware.blogspot.com/2016/06/kozy.html" - ], - "synonyms": [ - "QC" - ] - }, - "uuid": "47b5d261-11bd-4c7b-91f9-e5651578026a", - "value": "Kozy.Jozy" - }, - { - "description": "Ransomware kratosdimetrici@gmail.com", - "meta": { - "extensions": [ - ".kratos" - ], - "payment-method": "Bitcoin", - "price": "0.03", - "ransomnotes-filenames": [ - "README_ALL.html" - ], - "refs": [ - "https://twitter.com/demonslay335/status/746090483722686465", - "https://id-ransomware.blogspot.com/2016/06/kratoscrypt-ransomware-aes-256-0.html" - ] - }, - "uuid": "cc819741-830b-4859-bb7c-ccedf3356acd", - "value": "KratosCrypt" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "encryption": "AES-256", - "payment-method": "ransom", - "ransomnotes-filenames": [ - "KryptoLocker_README.txt" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/07/kryptolocker-ransomware-aes-256.html" - ] - }, - "uuid": "e68d4f37-704a-4f8e-9718-b12039fbe424", - "value": "KryptoLocker" - }, - { - "description": "Ransomware Variant of open-source MyLittleRansomware", - "meta": { - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes": [ - "@__help__@" - ], - "refs": [ - "https://twitter.com/struppigel/status/847689644854595584", - "http://id-ransomware.blogspot.com/2017/03/lanran-ransomware.html" - ] - }, - "uuid": "9e152871-fb16-475d-bf3b-f3b870d0237a", - "value": "LanRan" - }, - { - "description": "Ransomware Encrypts first 0x2000 and last 0x2000 bytes. Via remote attacker", - "meta": { - "extensions": [ - ".LeChiffre" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "How to decrypt LeChiffre files.html" - ], - "refs": [ - "https://decrypter.emsisoft.com/lechiffre", - "https://blog.malwarebytes.org/threat-analysis/2016/01/lechiffre-a-manually-run-ransomware/", - "http://id-ransomware.blogspot.com/2016/05/lechiffre-ransomware.html" - ] - }, - "uuid": "ea1ba874-07e6-4a6d-82f0-e4ce4210e34e", - "value": "LeChiffre" - }, - { - "description": "Ransomware Variant of Kirk", - "meta": { - "extensions": [ - ".Licked" - ], - "payment-method": "Monero", - "price": "50 - 500", - "ransomnotes-filenames": [ - "RANSOM_NOTE.txt" - ], - "refs": [ - "https://twitter.com/JakubKroustek/status/842404866614038529", - "https://www.2-spyware.com/remove-lick-ransomware-virus.html" - ] - }, - "uuid": "f2e76070-0cea-4c9c-8d6b-1d847e777575", - "value": "Lick" - }, - { - "description": "Ransomware Linux Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "1 (450 $)", - "refs": [ - "https://labs.bitdefender.com/2015/11/linux-ransomware-debut-fails-on-predictable-encryption-key/" - ], - "synonyms": [ - "Linux.Encoder.{0,3}" - ] - }, - "uuid": "b4992483-a693-4e73-b39e-0f45c9f645b5", - "value": "Linux.Encoder" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://twitter.com/malwrhunterteam/status/845183290873044994", - "http://id-ransomware.blogspot.com/2017/03/lk-encryption-ransomware.html" - ] - }, - "uuid": "af52badb-3211-42b0-a1ac-e4d35d5829d7", - "value": "LK Encryption" - }, - { - "description": "Ransomware Targeting Spanish speaking victims", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".ENCRYPTED_BY_LLTP", - ".ENCRYPTED_BY_LLTPp" - ], - "payment-method": "Bitcoin", - "price": "0.2 (200 $)", - "ransomnotes-filenames": [ - "LEAME.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/new-lltp-ransomware-appears-to-be-a-rewritten-venus-locker/", - "http://id-ransomware.blogspot.com/2017/03/lltp-ransomware.html" - ] - }, - "uuid": "0cec6928-80c7-4085-ba47-cdc52177dfd3", - "value": "LLTP Locker" - }, - { - "description": "Ransomware has GUI", - "meta": { - "payment-method": "Bitcoin", - "price": "0.1", - "refs": [ - "http://www.bleepingcomputer.com/forums/t/577246/locker-ransomware-support-and-help-topic/page-32#entry3721545", - "https://id-ransomware.blogspot.com/2016/04/locker-ransomware-2015.html" - ], - "synonyms": [ - "LockeR" - ] - }, - "uuid": "abc7883c-244a-44ac-9c86-559dafa4eb63", - "value": "Locker" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locklock" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "READ_ME.TXT" - ], - "refs": [ - "https://www.bleepingcomputer.com/forums/t/626750/locklock-ransomware-locklock-help-support/", - "https://id-ransomware.blogspot.com/2016/09/locklock-ransomware.html" - ] - }, - "uuid": "7850bf92-394b-443b-8830-12f9ddbb50dc", - "value": "LockLock" - }, - { - "description": "Ransomware Affiliations with Dridex and Necurs botnets", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".locky", - ".zepto", - ".odin", - ".shit", - ".thor", - ".aesir", - ".zzzzz", - ".osiris", - "([A-F0-9]{32}).locky", - "([A-F0-9]{32}).zepto", - "([A-F0-9]{32}).odin", - "([A-F0-9]{32}).shit", - "([A-F0-9]{32}).thor", - "([A-F0-9]{32}).aesir", - "([A-F0-9]{32}).zzzzz", - "([A-F0-9]{32}).osiris", - ".lukitus" - ], - "payment-method": "Bitcoin", - "price": "3 - 5 - 7", - "ransomnotes": [ - "DesktopOSIRIS.(bmp|htm)", - "lukitus.bmp." - ], - "ransomnotes-filenames": [ - "_Locky_recover_instructions.txt", - "_Locky_recover_instructions.bmp", - "_HELP_instructions.txt", - "_HELP_instructions.bmp", - "_HOWDO_text.html", - "_WHAT_is.html", - "_INSTRUCTION.html", - "OSIRIS-[0-9]{4}.htm", - "lukitus.htm" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/new-locky-version-adds-the-zepto-extension-to-encrypted-files/", - "http://blog.trendmicro.com/trendlabs-security-intelligence/new-locky-ransomware-spotted-in-the-brazilian-underground-market-uses-windows-script-files/", - "https://nakedsecurity.sophos.com/2016/10/06/odin-ransomware-takes-over-from-zepto-and-locky/", - "https://www.bleepingcomputer.com/news/security/locky-ransomware-switches-to-egyptian-mythology-with-the-osiris-extension/", - "https://id-ransomware.blogspot.com/2016/02/locky.html" - ], - "synonyms": [ - "Locky-Odin", - "Locky-Osiris", - "Locky-Osiris 2016", - "Locky-Osiris 2017" - ] - }, - "related": [ - { - "dest-uuid": "24c9bb9f-1f9a-4e01-95d8-86c51733e11c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "8d51a22e-3485-4480-af96-8ed0305a7aa6", - "value": "Locky" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crime" - ], - "payment-method": "Dollars", - "price": "5", - "refs": [ - "https://id-ransomware.blogspot.com/2016/06/lortok-ransomware-aes-256-5.html" - ] - }, - "uuid": "bc23872a-7cd3-4a66-9d25-6b4e6f90cc4e", - "value": "Lortok" - }, - { - "description": "Ransomware Prepends filenames", - "meta": { - "extensions": [ - "oor." - ], - "payment-method": "Bitcoin", - "price": "4", - "refs": [ - "http://id-ransomware.blogspot.com/2016/04/lowlevel04-ransomware.html" - ] - }, - "uuid": "d4fb0463-6cd1-45ac-a7d2-6eea8be39590", - "value": "LowLevel04" - }, - { - "description": "Ransomware Does not encrypt Unlock code=suckmydicknigga", - "meta": { - "payment-method": "Bitcoin", - "price": "0.3", - "refs": [ - "https://twitter.com/jiriatvirlab/status/808015275367002113", - "http://id-ransomware.blogspot.com/2016/12/m4n1f3sto-ransomware.html" - ] - }, - "uuid": "f5d19af8-1c85-408b-818e-db50208d62b1", - "value": "M4N1F3STO" - }, - { - "description": "Ransomware OS X ransomware (PoC)", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://www.youtube.com/watch?v=9nJv_PN2m1Y" - ] - }, - "uuid": "f9214319-6ad4-4c4e-bc6d-fb710f61da48", - "value": "Mabouia" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "http://id-ransomware.blogspot.com/2017/03/macandchess-ransomware.html" - ] - }, - "uuid": "fae8bf6e-47d1-4449-a1c6-761a4970fc38", - "value": "MacAndChess" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".magic" - ], - "payment-method": "Bitcoin", - "price": "1 - 2", - "ransomnotes-filenames": [ - "DECRYPT_ReadMe1.TXT", - "DECRYPT_ReadMe.TXT" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/04/magic-ransomware.html" - ] - }, - "uuid": "31fa83fc-8247-4347-940a-e463acd66bac", - "value": "Magic" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256 + RSA-2048", - "extensions": [ - "[a-z]{4,6}" - ], - "payment-method": "Bitcoin", - "price": "1.4 - 3.9", - "ransomnotes-filenames": [ - "_DECRYPT_INFO_[extension pattern].html" - ], - "refs": [ - "https://blog.malwarebytes.org/threat-analysis/2016/03/maktub-locker-beautiful-and-dangerous/", - "http://id-ransomware.blogspot.com/2016/04/maktub-locker-ransomware.html" - ] - }, - "uuid": "ef6ceb04-243e-4783-b476-8e8e9f06e8a7", - "value": "MaktubLocker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".a19", - ".ap19" - ], - "payment-method": "Bitcoin", - "price": "0.7 - 1.1", - "ransomnotes-filenames": [ - "!!! Readme For Decrypt !!!.txt", - "ReadMeFilesDecrypt!!!.txt" - ], - "refs": [ - "https://securelist.ru/blog/issledovaniya/29376/polyglot-the-fake-ctb-locker/", - "https://www.proofpoint.com/us/threat-insight/post/MarsJoke-Ransomware-Mimics-CTB-Locker", - "http://id-ransomware.blogspot.com/2016/09/jokefrommars-ransomware.html" - ] - }, - "uuid": "933bd53f-5ccf-4262-a70c-c01a6f05af3e", - "value": "MarsJoke" - }, - { - "description": "Ransomware Targeting French victims", - "meta": { - "payment-method": "Bitcoin", - "price": "0.1", - "refs": [ - "https://twitter.com/siri_urz/status/840913419024945152" - ] - }, - "uuid": "ce5a82ef-d2a3-405c-ac08-3dca71057eb5", - "value": "Meister" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Email", - "ransomnotes-filenames": [ - "where_are_your_files.txt", - "readme_your_files_have_been_encrypted.txt" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/844614889620561924", - "http://id-ransomware.blogspot.com/2017/03/meteoritan-ransomware.html" - ] - }, - "uuid": "34f292d9-cb68-4bcf-a3db-a717362aca77", - "value": "Meteoritan" - }, - { - "description": "Ransomware Prepends files Demands 48.48 BTC", - "meta": { - "encryption": "AES", - "extensions": [ - "Lock." - ], - "payment-method": "Bitcoin", - "price": "48.48", - "refs": [ - "http://www.bleepingcomputer.com/forums/t/618457/microcop-ransomware-help-support-lock-mircop/", - "https://www.avast.com/ransomware-decryption-tools#!", - "http://blog.trendmicro.com/trendlabs-security-intelligence/instruction-less-ransomware-mircop-channels-guy-fawkes/", - "http://www.nyxbone.com/malware/Mircop.html", - "https://id-ransomware.blogspot.com/2016/06/mircop-ransomware-4848.html" - ], - "synonyms": [ - "Crypt888", - "MicroCop" - ] - }, - "uuid": "7dd326a5-1168-4309-98b1-f2146d9cf8c7", - "value": "MIRCOP" - }, - { - "description": "Ransomware Based on HiddenTear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".fucked", - ".fuck" - ], - "payment-method": "Bitcoin - Email", - "ransomnotes-filenames": [ - "READ_IT.txt" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/05/mireware-ransomware.html" - ] - }, - "uuid": "9f01ded7-99f6-4863-b3a3-9d32aabf96c3", - "value": "MireWare" - }, - { - "description": "Ransomware Packaged with Petya PDFBewerbungsmappe.exe", - "meta": { - "extensions": [ - ".([a-zA-Z0-9]{4})" - ], - "payment-method": "Bitcoin", - "price": "1.9338", - "ransomnotes": [ - "YOUR_FILES_ARE_ENCRYPTED.TXT " - ], - "ransomnotes-filenames": [ - "YOUR_FILES_ARE_ENCRYPTED.HTML" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/petya-is-back-and-with-a-friend-named-mischa-ransomware/", - "https://id-ransomware.blogspot.com/2016/05/petya-mischa-ransomware.html" - ], - "synonyms": [ - "\"Petya's little brother\"", - "Misha", - "Petya+Mischa", - "Petya-2" - ] - }, - "uuid": "a029df89-2bb1-409d-878b-a67572217a65", - "value": "Mischa" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "1.011 (400 $)", - "ransomnotes-filenames": [ - "READ_IT.txt" - ], - "refs": [ - "https://www.proofpoint.com/us/threat-insight/post/ransomware-explosion-continues-cryptflle2-brlock-mm-locker-discovered", - "https://id-ransomware.blogspot.com/2016/06/mm-locker-ransomware-aes-2256-1.html" - ], - "synonyms": [ - "Booyah" - ] - }, - "related": [ - { - "dest-uuid": "eee75995-321f-477f-8b57-eee4eedf4ba3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b95aa3fb-9f32-450e-8058-67d94f196913", - "value": "MM Locker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".KEYZ", - ".KEYH0LES" - ], - "payment-method": "Bitcoin", - "price": "4", - "ransomnotes": [ - "IMPORTANT.README" - ], - "ransomnotes-filenames": [ - "4-14-2016-INFECTION.TXT" - ], - "refs": [ - "http://nyxbone.com/malware/Mobef.html", - "http://researchcenter.paloaltonetworks.com/2016/07/unit42-cryptobit-another-ransomware-family-gets-an-update/", - "http://nyxbone.com/images/articulos/malware/mobef/0.png", - "http://id-ransomware.blogspot.com/2016/05/mobef-yakes-ransomware-4-bitcoins-2000.html" - ], - "synonyms": [ - "Yakes", - "CryptoBit" - ] - }, - "related": [ - { - "dest-uuid": "1903ed75-05f7-4019-b0b7-7a8f23f22194", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8fa6b51a-a48d-48dc-87ec-cf0d30ad66e8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "681f212a-af1b-4e40-a718-81b0dc46dc52", - "value": "Mobef" - }, - { - "description": "Ransomware Use the DarkLocker 5 porn screenlocker - Jigsaw variant", - "meta": { - "payment-method": "Bitcoin", - "price": "0.15 - 0.2", - "refs": [ - "https://twitter.com/malwrhunterteam/status/844826339186135040" - ] - }, - "uuid": "2702fb96-8118-4519-bd75-23eed40f25e9", - "value": "Monument" - }, - { - "description": "Ransomware Russian Koolova Variant", - "meta": { - "extensions": [ - ".кибер разветвитель" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "refs": [ - "https://twitter.com/JakubKroustek/status/815961663644008448", - "https://www.youtube.com/watch?v=dAVMgX8Zti4&feature=youtu.be&list=UU_TMZYaLIgjsdJMwurHAi4Q" - ] - }, - "uuid": "8ec55495-fb31-49c7-a720-40250b5e085f", - "value": "N-Splitter" - }, - { - "description": "Ransomware Filemaker: \"333333333333\"", - "meta": { - "payment-method": "Bitcoin", - "price": "1.5", - "ransomnotes-filenames": [ - "decrypt explanations.html" - ], - "refs": [ - "https://twitter.com/demonslay335/status/790608484303712256", - "https://twitter.com/demonslay335/status/831891344897482754", - "http://id-ransomware.blogspot.com/2016/09/n1n1n1-ransomware.html" - ], - "synonyms": [ - "N1N1N1" - ] - }, - "uuid": "a439b37b-e123-4b1d-9400-94aca70b223a", - "value": "n1n1n1" - }, - { - "description": "Ransomware no extension change, has a GUI", - "meta": { - "encryption": "AES-256 + RSA", - "payment-method": "Bitcoin", - "price": "0.1 (43 $)", - "ransomnotes-filenames": [ - "ATTENTION.RTF" - ], - "refs": [ - "http://github.com/Cyberclues/nanolocker-decryptor", - "https://id-ransomware.blogspot.com/2016/06/nanolocker-ransomware-aes-256-rsa-01.html" - ] - }, - "related": [ - { - "dest-uuid": "00e1373c-fddf-4b06-9770-e980cc0ada6b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "03a91686-c607-49a8-a4e2-2054833c0013", - "value": "NanoLocker" - }, - { - "description": "Ransomware 7zip (a0.exe) variant cannot be decrypted Encrypts the first 2048 Bytes", - "meta": { - "encryption": "XOR(255) + 7zip", - "extensions": [ - ".crypted" - ], - "payment-method": "Bitcoin", - "price": "0.39983 - 4", - "ransomnotes-filenames": [ - "Decrypted.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/nemucod", - "https://github.com/Antelox/NemucodFR", - "http://www.bleepingcomputer.com/news/security/decryptor-released-for-the-nemucod-trojans-crypted-ransomware/", - "https://blog.cisecurity.org/malware-analysis-report-nemucod-ransomware/", - "http://id-ransomware.blogspot.com/2016/04/nemucod-ransomware.html" - ], - "synonyms": [ - "Nemucod-7z", - "Nemucod-AES" - ] - }, - "uuid": "f1ee9ae8-b798-4e6f-8f98-874395d0fa18", - "value": "Nemucod" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "AES-256" - ], - "payment-method": "Bitcoin", - "price": "0.18 (100 $)", - "refs": [ - "http://blog.trendmicro.com/trendlabs-security-intelligence/netflix-scam-delivers-ransomware/", - "https://id-ransomware.blogspot.com/2017/01/netflix-ransomware.html" - ], - "synonyms": [ - "RANSOM_NETIX.A" - ] - }, - "uuid": "5d3ec71e-9e0f-498a-aa33-0433799e80b4", - "value": "Netix" - }, - { - "description": "Ransomware Does not encrypt the files / Files are destroyed", - "meta": { - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "!_RECOVERY_HELP_!.txt", - "HELP_ME_PLEASE.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/839221457360195589", - "http://id-ransomware.blogspot.com/2017/03/nhtnwcuf-ransomware.html" - ] - }, - "uuid": "1d8e8ca3-da2a-494c-9db3-5b1b6277c363", - "value": "Nhtnwcuf" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "mix of RSA and AES-256", - "extensions": [ - ".maktub", - ".__AiraCropEncrypted!" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1.5", - "ransomnotes-filenames": [ - "Recupere seus arquivos. Leia-me!.txt" - ], - "refs": [ - "https://decrypter.emsisoft.com/nmoreira", - "https://twitter.com/fwosar/status/803682662481174528", - "id-ransomware.blogspot.com/2016/11/nmoreira-ransomware.html" - ], - "synonyms": [ - "XRatTeam", - "XPan" - ] - }, - "uuid": "51f00a39-f4b9-4ed2-ba0d-258c6bf3f71a", - "value": "NMoreira" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "250 NZD (299 $)", - "refs": [ - "https://twitter.com/JakubKroustek/status/757267550346641408", - "https://www.bleepingcomputer.com/news/security/noobcrypt-ransomware-dev-shows-noobness-by-using-same-password-for-everyone/", - "https://id-ransomware.blogspot.com/2016/07/noobcrypt-ransomare-250-nzd.html" - ] - }, - "uuid": "aeb76911-ed45-4bf2-9a60-e023386e02a4", - "value": "NoobCrypt" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".nuclear55" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "!!_RECOVERY_instructions_!!.html", - "!!_RECOVERY_instructions_!!.txt" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/10/nuke-ransomware.html" - ] - }, - "uuid": "e0bcb7d2-6032-43a0-b490-c07430d8a598", - "value": "Nuke" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "_nullbyte" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/NullByteDecrypter.zip", - "https://www.bleepingcomputer.com/news/security/the-nullbyte-ransomware-pretends-to-be-the-necrobot-pokemon-go-application/", - "http://id-ransomware.blogspot.com/2016/08/nullbyte-ransomware.html" - ] - }, - "uuid": "460b700b-5d03-43f9-99e7-916ff180a036", - "value": "Nullbyte" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "XOR", - "extensions": [ - ".odcodc", - "C-email-abennaki@india.com-(NOMBRE_ARCHIVO.ext).odcodc" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "HOW_TO_RESTORE_FILES.txt" - ], - "refs": [ - "http://download.bleepingcomputer.com/BloodDolly/ODCODCDecoder.zip", - "http://www.nyxbone.com/malware/odcodc.html", - "https://twitter.com/PolarToffee/status/813762510302183424", - "http://www.nyxbone.com/images/articulos/malware/odcodc/1c.png", - "http://id-ransomware.blogspot.com/2016/05/odcodc-ransomware-rsa-2048.html" - ] - }, - "uuid": "f90724e4-c148-4479-ae1a-109498b4688f", - "value": "ODCODC" - }, - { - "description": "Ransomware email addresses overlap with .777 addresses", - "meta": { - "extensions": [ - ".cbf", - "email-[params].cbf" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "desk.bmp", - "desk.jpg" - ], - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547", - "http://bartblaze.blogspot.com.co/2016/02/vipasana-ransomware-new-ransom-on-block.html" - ], - "synonyms": [ - "Vipasana", - "Cryakl" - ] - }, - "related": [ - { - "dest-uuid": "4f3e494e-0e37-4894-94b2-741a8100f07a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "32fa6c53-b4fc-47f8-894c-1ea74180e02f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "3c51fc0e-42d8-4ff0-b1bd-5c8c20271a39", - "value": "Offline ransomware" - }, - { - "description": "Ransomware. Infection: drive-by-download; Platform: Windows; Extorsion by Prepaid Voucher", - "meta": { - "Encryption": "RSA", - "extensions": [ - ".LOL!", - ".OMG!" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "ransomnotes-filenames": [ - "how to get data.txt" - ], - "refs": [ - "https://arxiv.org/pdf/2102.06249.pdf" - ], - "synonyms": [ - "GPCode" - ] - }, - "related": [ - { - "dest-uuid": "127c3d76-6323-4363-93e0-cd06ade0dd52", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "7914f9c9-3257-464c-b918-3754c4d018af", - "value": "OMG! Ransomware" - }, - { - "description": "Ransomware Is a file infector (virus)", - "meta": { - "extensions": [ - ".EXE" - ], - "payment-method": "Bitcoin", - "price": "250 $", - "refs": [ - "http://news.thewindowsclub.com/operation-global-iii-ransomware-decryption-tool-released-70341/" - ] - }, - "uuid": "e5800883-c663-4eb0-b05e-6034df5bc6e0", - "value": "Operation Global III" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "dummy_file.encrypted", - "dummy_file.encrypted.[extension]" - ], - "payment-method": "Bitcoin", - "price": "0.29499335", - "ransomnotes-filenames": [ - "log.txt" - ], - "refs": [ - "https://twitter.com/JakubKroustek/status/842342996775448576", - "https://id-ransomware.blogspot.com/2016/10/cryptowire-ransomware.html" - ], - "synonyms": [ - "CryptoWire" - ] - }, - "related": [ - { - "dest-uuid": "bc0c1e48-102c-4e6b-9b86-c442c4798159", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "4bb11db7-17a0-4536-b817-419ae6299004", - "value": "Owl" - }, - { - "description": "Ransomware has a live support chat", - "meta": { - "extensions": [ - ".padcrypt" - ], - "payment-method": "Bitcoin", - "price": "0.8", - "ransomnotes-filenames": [ - "IMPORTANT READ ME.txt", - "File Decrypt Help.html" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/padcrypt-the-first-ransomware-with-live-support-chat-and-an-uninstaller/", - "https://twitter.com/malwrhunterteam/status/798141978810732544", - "http://id-ransomware.blogspot.com/2016/04/padcrypt-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "c21335f5-b145-4029-b1bc-161362c7ce80", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "57c5df76-e72f-41b9-be29-89395f83a77c", - "value": "PadCrypt" - }, - { - "description": "Ransomware Unlock code is: ajVr/G\\ RJz0R", - "meta": { - "payment-method": "no ransom", - "refs": [ - "https://twitter.com/BleepinComputer/status/811635075158839296" - ] - }, - "uuid": "8f41c9ce-9bd4-4bbd-96d7-c965d1621be7", - "value": "Padlock Screenlocker" - }, - { - "description": "Ransomware Targeting macOS users", - "meta": { - "extensions": [ - ".crypt" - ], - "payment-method": "Bitcoin", - "price": "0.25", - "ransomnotes-filenames": [ - "README!.txt" - ], - "refs": [ - "https://blog.malwarebytes.com/cybercrime/2017/02/decrypting-after-a-findzip-ransomware-infection/", - "https://www.bleepingcomputer.com/news/security/new-macos-patcher-ransomware-locks-data-for-good-no-way-to-recover-your-files/" - ] - }, - "related": [ - { - "dest-uuid": "091c9923-5939-4bde-9db5-56abfb51f1a2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "bad1057c-4f92-4747-a0ec-31bcc062dab8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "e211ea8d-5042-48ae-86c6-15186d1f8dba", - "value": "Patcher" - }, - { - "description": "Ransomware encrypts disk partitions PDFBewerbungsmappe.exe", - "meta": { - "encryption": "Modified Salsa20", - "payment-method": "Bitcoin - Website (onion)", - "ransomnotes-filenames": [ - "YOUR_FILES_ARE_ENCRYPTED.TXT" - ], - "refs": [ - "http://www.thewindowsclub.com/petya-ransomware-decrypt-tool-password-generator", - "https://www.youtube.com/watch?v=mSqxFjZq_z4", - "https://blog.malwarebytes.org/threat-analysis/2016/04/petya-ransomware/", - "https://www.bleepingcomputer.com/news/security/petya-ransomware-returns-with-goldeneye-version-continuing-james-bond-theme/" - ], - "synonyms": [ - "Goldeneye" - ] - }, - "related": [ - { - "dest-uuid": "34c9dbaa-97ac-4e1e-9eca-b7c492d67efc", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ac7affb8-971d-4c05-84f0-172b61d007d7", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "7c5a1e93-7ab2-4b08-ada9-e82c4feaed0a", - "value": "Petya" - }, - { - "description": "Ransomware Coded by \"The_Rainmaker\"", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked", - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.3", - "refs": [ - "https://decrypter.emsisoft.com/philadelphia", - "www.bleepingcomputer.com/news/security/the-philadelphia-ransomware-offers-a-mercy-button-for-compassionate-criminals/", - "http://id-ransomware.blogspot.ru/2016/09/philadelphia-ransomware.html" - ] - }, - "uuid": "6fd25982-9cf8-4379-a126-433c91aaadf2", - "value": "Philadelphia" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".id-[victim_id]-maestro@pizzacrypts.info" - ], - "payment-method": "Email", - "refs": [ - "http://download.bleepingcomputer.com/BloodDolly/JuicyLemonDecoder.zip", - "https://id-ransomware.blogspot.com/2016/07/pizzacrypts-ransomware-1.html" - ] - }, - "uuid": "2482122b-1df6-488e-8867-215b165a4f66", - "value": "PizzaCrypts" - }, - { - "description": "Ransomware Based on Hidden Tear", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin - Email", - "refs": [ - "http://www.nyxbone.com/malware/pokemonGO.html", - "http://www.bleepingcomputer.com/news/security/pokemongo-ransomware-installs-backdoor-accounts-and-spreads-to-other-drives/", - "https://id-ransomware.blogspot.com/2016/08/pokemongo-ransomware-aes-256.html" - ] - }, - "uuid": "8b151275-d4c4-438a-9d06-92da2835586d", - "value": "PokemonGO" - }, - { - "description": "Ransomware Immitates CTB-Locker", - "meta": { - "encryption": "AES-256", - "payment-method": "Website (onion)", - "refs": [ - "https://support.kaspersky.com/8547", - "https://securelist.com/blog/research/76182/polyglot-the-fake-ctb-locker/" - ] - }, - "related": [ - { - "dest-uuid": "5ee77368-5e09-4016-ae73-82b99e830832", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b22cafb4-ccef-4935-82f4-631a6e539b8e", - "value": "Polyglot" - }, - { - "description": "Ransomware Open-sourced PowerShell", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".locky" - ], - "payment-method": "Bitcoin", - "price": "500 $", - "refs": [ - "https://github.com/pan-unit42/public_tools/blob/master/powerware/powerware_decrypt.py", - "https://download.bleepingcomputer.com/demonslay335/PowerLockyDecrypter.zip", - "https://www.carbonblack.com/2016/03/25/threat-alert-powerware-new-ransomware-written-in-powershell-targets-organizations-via-microsoft-word/", - "http://researchcenter.paloaltonetworks.com/2016/07/unit42-powerware-ransomware-spoofing-locky-malware-family/", - "http://id-ransomware.blogspot.com/2016/04/powerware-ransomware.html" - ], - "synonyms": [ - "PoshCoder" - ] - }, - "related": [ - { - "dest-uuid": "5c5beab9-614c-4c86-b369-086234ddb43c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "9fa93bb7-2997-4864-aa0e-0e667990dec8", - "value": "PowerWare" - }, - { - "description": "Ransomware no decryption possible, throws key away, destroys the files", - "meta": { - "encryption": "AES", - "payment-method": "Website (onion)", - "ransomnotes-filenames": [ - "DECRYPT_INSTRUCTION.html" - ] - }, - "uuid": "b54d59d7-b604-4b01-8002-5a2930732ca6", - "value": "PowerWorm" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "[a-z]{4,6},[0-9]" - ], - "payment-method": "Bitcoin", - "price": "3 (1 800 $)", - "ransomnotes": [ - ".*id*" - ], - "ransomnotes-filenames": [ - "!_HOW_TO_RESTORE_[extension].TXT", - "!_HOW_TO_RESTORE_[extension].html", - "!_HOW_TO_RESTORE_*id*.txt", - "@_USE_TO_FIX_JJnY.txt" - ], - "refs": [ - "https://hshrzd.wordpress.com/2016/11/17/princess-locker-decryptor/", - "https://www.bleepingcomputer.com/news/security/introducing-her-royal-highness-the-princess-locker-ransomware/", - "https://blog.malwarebytes.com/threat-analysis/2016/11/princess-ransomware/", - "http://id-ransomware.blogspot.com/2016/09/princess-locker-ransomware.html" - ] - }, - "uuid": "7c8ff7e5-2cad-48e8-92e8-4c8226933cbc", - "value": "Princess Locker" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "MoneyPak", - "price": "300 $", - "refs": [ - "http://www.enigmasoftware.com/prismyourcomputerhasbeenlockedransomware-removal/" - ] - }, - "uuid": "c0ebfb75-254d-4d85-9d02-a7af8e655068", - "value": "PRISM" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://twitter.com/jiriatvirlab/status/803297700175286273" - ] - }, - "uuid": "1da6653c-8657-4cdc-9eaf-0df9d2ebbf10", - "value": "Ps2exe" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "1 - 2", - "ransomnotes-filenames": [ - "Ransomware.txt" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/846705481741733892", - "http://id-ransomware.blogspot.com/2017/03/r-ransomware.html" - ], - "synonyms": [ - "NM3" - ] - }, - "uuid": "f7cd8956-2825-4104-94b1-e9589ab1089a", - "value": "R" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".crypt" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "DECRYPTION INSTRUCTIONS.txt", - "rtext.txt" - ], - "refs": [ - "https://otx.alienvault.com/pulse/57976b52b900fe01376feb01/", - "http://id-ransomware.blogspot.com/2016/07/r980-ransomware-aes-256-rsa4096-05.html" - ] - }, - "uuid": "6a7ebb0a-78bc-4fdc-92ae-1b02976b5499", - "value": "R980" - }, - { - "description": "Ransomware Possible affiliation with Pony", - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.39 (215 $)", - "ransomnotes-filenames": [ - "!!!README!!![id].rtf" - ], - "refs": [ - "https://reaqta.com/2016/06/raa-ransomware-delivering-pony/", - "http://www.bleepingcomputer.com/news/security/the-new-raa-ransomware-is-created-entirely-using-javascript/", - "https://id-ransomware.blogspot.com/2016/06/raa-ransomware-aes-256-039-250.html" - ], - "synonyms": [ - "RAA", - "RAA SEP" - ] - }, - "uuid": "b6d4faa1-6d76-42ff-8a18-238eb70cff06", - "value": "RAA encryptor" - }, - { - "description": "Ransomware RaaS Copy of Ranion RaaS", - "meta": { - "payment-method": "Bitcoin", - "price": "0.05", - "refs": [ - "https://twitter.com/CryptoInsane/status/846181140025282561" - ] - }, - "uuid": "4a95257a-6646-492f-93eb-d15dff7ce1eb", - "value": "Rabion" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".RDM", - ".RRK", - ".RAD", - ".RADAMANT" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "YOUR_FILES.url" - ], - "refs": [ - "https://decrypter.emsisoft.com/radamant", - "http://www.bleepingcomputer.com/news/security/new-radamant-ransomware-kit-adds-rdm-extension-to-encrypted-files/", - "http://www.nyxbone.com/malware/radamant.html", - "https://id-ransomware.blogspot.com/2016/04/radamant-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "98bcb2b9-bc3a-4ffb-859a-94bd03c1cc3c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "674c3bf6-2e16-427d-ab0f-b91676a460cd", - "value": "Radamant" - }, - { - "description": "Ransomware Files might be partially encrypted", - "meta": { - "extensions": [ - ".locked", - ".kraken", - ".darkness", - ".nochance", - ".oshit", - ".oplata@qq_com", - ".relock@qq_com", - ".crypto", - ".helpdecrypt@ukr.net", - ".pizda@qq_com", - ".dyatel@qq_com", - "_ryp", - ".nalog@qq_com", - ".chifrator@qq_com", - ".gruzin@qq_com", - ".troyancoder@qq_com", - ".encrypted", - ".cry", - ".AES256", - ".enc", - ".hb15", - ".coderksu@gmail_com_id[0-9]{2,3}", - ".crypt@india.com.[\\w]{4,12}", - "!@#$%___________%$#@.mail" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "\\fud.bmp", - "\\paycrypt.bmp", - "\\strongcrypt.bmp", - "\\maxcrypt.bmp", - "%APPDATA%\\Roaming\\.bmp" - ], - "refs": [ - "https://support.kaspersky.com/us/viruses/disinfection/10556", - "https://id-ransomware.blogspot.com/2016/07/bandarchor-ransomware-aes-256.html" - ], - "synonyms": [ - "Agent.iih", - "Aura", - "Autoit", - "Pletor", - "Rotor", - "Lamer", - "Isda", - "Cryptokluchen", - "Bandarchor" - ] - }, - "related": [ - { - "dest-uuid": "af50d07e-3fc5-4014-9ac5-f5466cf042bc", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "c85a41a8-a0a1-4963-894f-84bb980e6e86", - "value": "Rakhni" - }, - { - "description": "Ransomware Based on the DUMB ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "0.3169" - }, - "uuid": "5b81ea66-9a44-43d8-bceb-22e5b0582f8d", - "value": "Ramsomeer" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "locked-.[a-zA-Z]{4}" - ], - "payment-method": "PaySafeCard", - "price": "1000 $", - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/8547" - ] - }, - "uuid": "d45f089b-efc7-45f8-a681-845374349d83", - "value": "Rannoh" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".zXz" - ], - "payment-method": "Bitcoin", - "ransomnotes": [ - "VictemKey_0_5", - "VictemKey_5_30", - "VictemKey_30_100", - "VictemKey_100_300", - "VictemKey_300_700", - "VictemKey_700_2000", - "VictemKey_2000_3000", - "VictemKey_3000" - ], - "ransomnotes-filenames": [ - "zXz.html" - ], - "refs": [ - "https://github.com/pan-unit42/public_tools/tree/master/ranran_decryption", - "http://researchcenter.paloaltonetworks.com/2017/03/unit42-targeted-ransomware-attacks-middle-eastern-government-organizations-political-purposes/", - "https://www.bleepingcomputer.com/news/security/new-ranran-ransomware-uses-encryption-tiers-political-messages/" - ], - "synonyms": [ - "ZXZ" - ] - }, - "uuid": "e01a0cfa-2c8c-4e08-963a-4fa1e8cc6a34", - "value": "RanRan" - }, - { - "description": "Ransomware Doesn't encrypt user files", - "meta": { - "payment-method": "Bitcoin", - "price": "100 $", - "refs": [ - "https://www.proofpoint.com/us/threat-insight/post/ransoc-desktop-locking-ransomware-ransacks-local-files-social-media-profiles", - "https://www.bleepingcomputer.com/news/security/ransoc-ransomware-extorts-users-who-accessed-questionable-content/" - ] - }, - "related": [ - { - "dest-uuid": "5310903e-0704-4ca4-ab1b-52d243dddb06", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "f0fcbac5-6216-4c3c-adcb-3aa06ab23340", - "value": "Ransoc" - }, - { - "description": "Ransomware no extension change, Javascript Ransomware", - "meta": { - "encryption": "AES", - "payment-method": "Bitcoin", - "price": "1", - "refs": [ - "http://id-ransomware.blogspot.com/2016/04/ransom32.html" - ] - }, - "uuid": "d74e2fa6-6b8d-49ed-80f9-07b274eecef8", - "value": "Ransom32" - }, - { - "description": "Ransomware Locks the desktop", - "meta": { - "encryption": "Asymmetric 1024 ", - "payment-method": "Bitcoin", - "price": "500 $", - "refs": [ - "https://www.symantec.com/security_response/writeup.jsp?docid=2009-041513-1400-99&tabid=2" - ] - }, - "uuid": "24f98123-192c-4e31-b2ee-4c77afbdc3be", - "value": "RansomLock" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "1 - 50", - "ransomnotes-filenames": [ - "RarVault.htm" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/09/rarvault-ransomware.html" - ] - }, - "uuid": "c8ee96a3-ac22-40c7-8ed2-df67aeaca08d", - "value": "RarVault" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-128", - "extensions": [ - ".razy", - ".fear" - ], - "payment-method": "Link", - "refs": [ - "http://www.nyxbone.com/malware/Razy(German).html", - "http://nyxbone.com/malware/Razy.html", - "http://id-ransomware.blogspot.com/2016/08/razy-ransomware-aes.html" - ] - }, - "uuid": "f2a38c7b-054e-49ab-aa0e-67a7aac71837", - "value": "Razy" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".vscrypt", - ".infected", - ".bloc", - ".korrektor" - ], - "payment-method": "Bitcoin Email", - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/4264" - ] - }, - "uuid": "08f519f4-df8f-4baf-b7ac-c7a0c66f7e74", - "value": "Rector" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".rekt" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "Readme.txt" - ], - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/4264", - "http://id-ransomware.blogspot.com/2016/08/rektlocker-ransomware.html" - ] - }, - "uuid": "5448f038-0558-45c7-bda7-76950f82846a", - "value": "RektLocker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".remind", - ".crashed" - ], - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes": [ - "decypt_your_files.html " - ], - "refs": [ - "http://www.nyxbone.com/malware/RemindMe.html", - "http://i.imgur.com/gV6i5SN.jpg", - "http://id-ransomware.blogspot.com/2016/05/remindme-ransomware-2.html" - ] - }, - "uuid": "0120015c-7d37-469c-a966-7a0d42166e67", - "value": "RemindMe" - }, - { - "description": "Ransomware possibly related with Chimera", - "meta": { - "encryption": "Curve25519 + ChaCha", - "extensions": [ - ".rokku" - ], - "payment-method": "Bitcoin", - "price": "0.2403 (100.29 $)", - "ransomnotes-filenames": [ - "README_HOW_TO_UNLOCK.TXT", - "README_HOW_TO_UNLOCK.HTML" - ], - "refs": [ - "https://blog.malwarebytes.org/threat-analysis/2016/04/rokku-ransomware/", - "https://id-ransomware.blogspot.com/2016/04/rokku-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "38f57823-ccc2-424b-8140-8ba30325af9c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "61184aea-e87b-467d-b36e-cfc75ccb242f", - "value": "Rokku" - }, - { - "description": "Ransomware Stores your files in a password protected RAR file", - "meta": { - "payment-method": "Bitcoin", - "price": "0.35", - "refs": [ - "https://twitter.com/siri_urz/status/842452104279134209", - "https://id-ransomware.blogspot.com/2017/02/allyourdocuments-ransomware.html" - ] - }, - "uuid": "e88a7509-9c79-42c1-8b0c-5e63af8e25b5", - "value": "RoshaLock" - }, - { - "description": "Ransomware Based on HT/EDA2 Utilizes the Jigsaw Ransomware background", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://twitter.com/struppigel/status/801812325657440256" - ] - }, - "uuid": "266b366b-2b4f-41af-a30f-eab1c63c9976", - "value": "Runsomewere" - }, - { - "description": "Ransomware Variant of the Philadelphia ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "0.3", - "refs": [ - "https://twitter.com/struppigel/status/823925410392080385" - ] - }, - "uuid": "1149197c-89e7-4a8f-98aa-40ac0a9c0914", - "value": "RussianRoulette" - }, - { - "description": "Ransomware Variant of CryPy", - "meta": { - "payment-method": "Email", - "refs": [ - "https://twitter.com/malwrhunterteam/status/845356853039190016", - "http://id-ransomware.blogspot.com/2017/03/sadstory-ransomware.html" - ] - }, - "uuid": "6d81cee2-6c99-41fb-8b54-6581422d85dc", - "value": "SADStory" - }, - { - "description": "Ransomware Sage 2.2 deletes volume snapshots through vssadmin.exe, disables startup repair, uses process wscript.exe to execute a VBScript, and coordinates the execution of scheduled tasks via schtasks.exe.", - "meta": { - "extensions": [ - ".sage" - ], - "payment-method": "Bitcoin", - "price": "0.52803 (625 $)", - "refs": [ - "https://malwarebreakdown.com/2017/03/16/sage-2-2-ransomware-from-good-man-gate", - "https://malwarebreakdown.com/2017/03/10/finding-a-good-man/" - ] - }, - "uuid": "eacf3aee-ffb1-425a-862f-874e444a218d", - "value": "Sage 2.2" - }, - { - "description": "Ransomware Targeted attacks -Jexboss -PSExec -Hyena", - "meta": { - "encryption": "AES(256) + RSA(2096)", - "extensions": [ - ".encryptedAES", - ".encryptedRSA", - ".encedRSA", - ".justbtcwillhelpyou", - ".btcbtcbtc", - ".btc-help-you", - ".only-we_can-help_you", - ".iwanthelpuuu", - ".notfoundrans", - ".encmywork", - ".VforVendetta", - ".theworldisyours", - ".Whereisyourfiles", - ".helpmeencedfiles", - ".powerfulldecrypt", - ".noproblemwedecfiles", - ".weareyourfriends", - ".otherinformation", - ".letmetrydecfiles", - ".encryptedyourfiles", - ".weencedufiles", - ".iaufkakfhsaraf", - ".cifgksaffsfyghd", - ".iloveworld", - ".weapologize" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "HELP_DECRYPT_YOUR_FILES.html", - "###-READ-FOR-HELLPP.html", - "000-PLEASE-READ-WE-HELP.html", - "CHECK-IT-HELP-FILES.html", - "WHERE-YOUR-FILES.html", - "HELP-ME-ENCED-FILES.html", - "WE-MUST-DEC-FILES.html", - "000-No-PROBLEM-WE-DEC-FILES.html", - "TRY-READ-ME-TO-DEC.html", - "000-IF-YOU-WANT-DEC-FILES.html", - "LET-ME-TRY-DEC-FILES.html", - "001-READ-FOR-DECRYPT-FILES.html", - "READ-READ-READ.html", - "IF_WANT_FILES_BACK_PLS_READ.html", - "READ_READ_DEC_FILES.html", - "HOW_TO_DECRYPT_FILES.html", - "HELP_FOR_DECRYPT_FILE.html", - "I_WILL_HELP_YOU_DECRYPT.html", - "PLEASE_READ_FOR_DECRYPT_FILES.html", - "WE-CAN-HELP-U.html", - "0001-WE-CAN-HELP-U.html", - "SORRY-FOR-FILES.html" - ], - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/SamSamStringDecrypter.zip", - "http://blog.talosintel.com/2016/03/samsam-ransomware.html", - "http://www.intelsecurity.com/advanced-threat-research/content/Analysis_SamSa_Ransomware.pdf", - "https://www.bleepingcomputer.com/news/security/new-samsam-variant-requires-special-password-before-infection/", - "https://www.bleepingcomputer.com/news/security/samsam-ransomware-crew-made-nearly-6-million-from-ransom-payments/", - "https://www.sophos.com/en-us/medialibrary/PDFs/technical-papers/SamSam-The-Almost-Six-Million-Dollar-Ransomware.pdf", - "https://id-ransomware.blogspot.com/2016/03/samsam.html" - ], - "synonyms": [ - "samsam.exe", - "MIKOPONI.exe", - "RikiRafael.exe", - "showmehowto.exe", - "SamSam Ransomware", - "SamSam", - "Samsam", - "Samas" - ] - }, - "related": [ - { - "dest-uuid": "696d78cb-1716-4ca0-b678-c03c7cfec19a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "731e4a5e-35f2-47b1-80ba-150b95fdc14d", - "value": "Samas-Samsam" - }, - { - "description": "Ransomware Based on HiddenTear, but heavily modified keygen", - "meta": { - "encryption": "AES-256 + RSA-2096", - "extensions": [ - ".sanction" - ], - "payment-method": "Bitcoin", - "price": "3", - "ransomnotes-filenames": [ - "DECRYPT_YOUR_FILES.HTML" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/05/sanction-ransomware-3.html" - ] - }, - "uuid": "e7b69fbe-26ba-49df-aa62-a64525f89343", - "value": "Sanction" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256 + RSA-2048", - "extensions": [ - ".wallet" - ], - "payment-method": "Bitcoin", - "price": "6", - "ransomnotes-filenames": [ - "RESTORE_ALL_DATA.html" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/sanctions-ransomware-makes-fun-of-usa-sanctions-against-russia/", - "http://id-ransomware.blogspot.com/2017/03/sanctions-2017-ransomware.html" - ], - "synonyms": [ - "Sanctions 2017" - ] - }, - "uuid": "7b517c02-9f93-44c7-b957-10346803c43c", - "value": "Sanctions" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".enc" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "refs": [ - "https://twitter.com/BleepinComputer/status/835955409953357825" - ] - }, - "uuid": "6e49ecfa-1c25-4841-ae60-3b1c3c9c7710", - "value": "Sardoninir" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - "Sarah_G@ausi.com___" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "!satana!.txt" - ], - "refs": [ - "https://blog.malwarebytes.com/threat-analysis/2016/06/satana-ransomware/", - "https://blog.kaspersky.com/satana-ransomware/12558/", - "https://id-ransomware.blogspot.com/2016/06/satana-ransomware-0.html" - ] - }, - "related": [ - { - "dest-uuid": "09b555be-8bac-44b2-8741-922ee0b87880", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "a127a59e-9e4c-4c2b-b833-cabd076c3016", - "value": "Satana" - }, - { - "description": "Ransomware", - "meta": { - "refs": [ - "http://securelist.com/blog/research/69481/a-flawed-ransomware-encryptor/" - ] - }, - "uuid": "c0c685b8-a59d-4922-add9-e572d5fd48cd", - "value": "Scraper" - }, - { - "description": "Ransomware DetoxCrypto Variant", - "meta": { - "encryption": "AES", - "payment-method": "Euros", - "price": "50", - "refs": [ - "http://www.nyxbone.com/malware/Serpico.html", - "http://id-ransomware.blogspot.com/2016/08/serpico-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "0d4ca924-7e7e-4385-b14d-f504b4d206e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "bd4bfbab-c21d-4971-b70c-b180bcf40630", - "value": "Serpico" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "50 - 100 - 200 $", - "ransomnotes-filenames": [ - "Readme.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/the-shark-ransomware-project-allows-to-create-your-own-customized-ransomware/", - "http://www.bleepingcomputer.com/news/security/shark-ransomware-rebrands-as-atom-for-a-fresh-start/" - ], - "synonyms": [ - "Atom" - ] - }, - "related": [ - { - "dest-uuid": "ff471870-7c9a-4122-ba89-489fc819660b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "503c9910-902f-4bae-8c33-ea29db8bdd7f", - "value": "Shark" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".shino" - ], - "payment-method": "no ransom", - "refs": [ - "https://twitter.com/JakubKroustek/status/760560147131408384", - "http://www.bleepingcomputer.com/news/security/new-educational-shinolocker-ransomware-project-released/", - "https://id-ransomware.blogspot.com/2016/08/shinolocker-ransomware.html" - ] - }, - "uuid": "bc029327-ee34-4eba-8933-bd85f2a1e9d1", - "value": "ShinoLocker" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "文件解密帮助.txt" - ], - "refs": [ - "http://www.nyxbone.com/malware/chineseRansom.html", - "http://blog.trendmicro.com/trendlabs-security-intelligence/chinese-language-ransomware-makes-appearance/", - "http://id-ransomware.blogspot.com/2016/05/chinese-ransomware.html" - ], - "synonyms": [ - "KinCrypt" - ] - }, - "related": [ - { - "dest-uuid": "77c20bd9-5403-4f99-bae5-c54f3f38a6b6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b9963d52-a391-4e9c-92e7-d2a147d5451f", - "value": "Shujin" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES", - "extensions": [ - ".~" - ], - "payment-method": "Bitcoin", - "price": "0.8", - "ransomnotes-filenames": [ - "_RECOVER_INSTRUCTIONS.ini" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/the-shark-ransomware-project-allows-to-create-your-own-customized-ransomware/", - "https://id-ransomware.blogspot.com/2016/07/tilde-ransomware-aes-08.html" - ], - "synonyms": [ - "Tilde" - ] - }, - "uuid": "2709b2ff-a2be-49a9-b268-2576170a5dff", - "value": "Simple_Encoder" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-filenames": [ - "READ_IT.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/pompous-ransomware-dev-gets-defeated-by-backdoor/", - "http://www.nyxbone.com/malware/SkidLocker.html", - "http://id-ransomware.blogspot.com/2016/04/pompous-ransomware.html" - ], - "synonyms": [ - "Pompous" - ] - }, - "uuid": "44b6b99e-b1d9-4605-95c2-55c14c7c25be", - "value": "SkidLocker" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "no ransom", - "refs": [ - "https://www.bleepingcomputer.com/news/security/smash-ransomware-is-cute-rather-than-dangerous/" - ] - }, - "uuid": "27283e74-abc6-4d8a-bcb6-a60804b8e264", - "value": "Smash!" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".encrypted" - ], - "payment-method": "Bitcoin", - "price": "0.66 (300 $)", - "ransomnotes-filenames": [ - "_HOW_TO_Decrypt.bmp" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/08/smrss32-ransomware.html" - ] - }, - "uuid": "cd21bb2a-0c6a-463b-8c0e-16da251f69ae", - "value": "Smrss32" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".RSNSlocked", - ".RSplited" - ], - "payment-method": "Bitcoin", - "price": "0.66 (300 $)", - "ransomnotes-filenames": [ - "READ_Me.txt" - ], - "refs": [ - "http://nyxbone.com/malware/SNSLocker.html", - "http://nyxbone.com/images/articulos/malware/snslocker/16.png", - "http://id-ransomware.blogspot.com/2016/05/sns-locker-ransomware-aes-256-066.html" - ] - }, - "uuid": "82658f48-6a62-4dee-bd87-382e76b84c3d", - "value": "SNSLocker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".sport" - ], - "payment-method": "Bitcoin" - }, - "uuid": "9526efea-8853-42f2-89be-a04ee1ca4c7d", - "value": "Sport" - }, - { - "description": "Ransomware Coded by \"The_Rainmaker\" Randomly deletes a file every 6hrs up to 96hrs then deletes decryption key", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "Random message includes bitcoin wallet address with instructions" - ], - "refs": [ - "https://success.trendmicro.com/portal_kb_articledetail?solutionid=1114221", - "http://www.bleepingcomputer.com/news/security/stampado-ransomware-campaign-decrypted-before-it-started/", - "https://decrypter.emsisoft.com/stampado", - "https://cdn.streamable.com/video/mp4/kfh3.mp4", - "http://blog.trendmicro.com/trendlabs-security-intelligence/the-economics-behind-ransomware-prices/", - "https://id-ransomware.blogspot.com/2016/07/stampado-ransomware-1.html" - ] - }, - "uuid": "6b8729b0-7ffc-4d07-98de-e5210928b274", - "value": "Stampado" - }, - { - "description": "Ransomware Based on EDA2, shows Guy Fawkes mask", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "500 - 1000 $", - "refs": [ - "http://www.nyxbone.com/malware/Strictor.html" - ] - }, - "uuid": "d75bdd85-032a-46b7-a339-257fd5656c11", - "value": "Strictor" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".surprise", - ".tzu" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 25", - "ransomnotes": [ - "DECRYPTION_HOWTO.Notepad" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/05/surprise-ransomware-aes-256.html" - ] - }, - "uuid": "6848b77c-92c8-40ec-90ac-9c14b9f17272", - "value": "Surprise" - }, - { - "description": "Ransomware Still in development, shows FileIce survey", - "meta": { - "payment-method": "no ransom", - "ransomnotes-filenames": [ - "ThxForYurTyme.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/news/security/in-dev-ransomware-forces-you-do-to-survey-before-unlocking-computer/" - ] - }, - "uuid": "11725992-3634-4715-ae17-b6f5ed13b877", - "value": "Survey" - }, - { - "description": "Ransomware Exploited Synology NAS firmware directly over WAN", - "meta": { - "payment-method": "Website (onion)" - }, - "uuid": "27740d5f-30cf-4c5c-812c-15c0918ce9f0", - "value": "SynoLocker" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".szf" - ], - "payment-method": "Email", - "refs": [ - "http://now.avg.com/dont-pay-the-ransom-avg-releases-six-free-decryption-tools-to-retrieve-your-files/", - "https://id-ransomware.blogspot.com/2016/06/szflocker-polish-ransomware-email.html" - ] - }, - "uuid": "a7845bbe-d7e6-4c7b-a9b8-dccbd93bc4b2", - "value": "SZFLocker" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".___xratteamLucked" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "Como descriptografar os seus arquivos.txt" - ], - "refs": [ - "https://securelist.com/blog/research/76153/teamxrat-brazilian-cybercrime-meets-ransomware/" - ] - }, - "uuid": "65a31863-4f59-4c66-bc2d-31e8fb68bbe8", - "value": "TeamXrat" - }, - { - "description": "Ransomware Factorization", - "meta": { - "extensions": [ - ".vvv", - ".ecc", - ".exx", - ".ezz", - ".abc", - ".aaa", - ".zzz", - ".xyz" - ], - "payment-method": "Bitcoin", - "ransomnotes-filenames": [ - "HELP_TO_SAVE_FILES.txt", - "Howto_RESTORE_FILES.html" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/576600/tesladecoder-released-to-decrypt-exx-ezz-ecc-files-encrypted-by-teslacrypt/", - "http://www.talosintel.com/teslacrypt_tool/" - ], - "synonyms": [ - "AlphaCrypt" - ] - }, - "uuid": "af92c71e-935e-4486-b4e7-319bf16d622e", - "value": "TeslaCrypt 0.x - 2.2.0" - }, - { - "description": "Ransomware 4.0+ has no extension", - "meta": { - "encryption": "AES-256 + ECHD + SHA1", - "extensions": [ - ".micro", - ".xxx", - ".ttt", - ".mp3" - ], - "payment-method": "Bitcoin", - "refs": [ - "http://www.bleepingcomputer.com/forums/t/576600/tesladecoder-released-to-decrypt-exx-ezz-ecc-files-encrypted-by-teslacrypt/", - "http://www.welivesecurity.com/2016/05/18/eset-releases-decryptor-recent-variants-teslacrypt-ransomware/", - "https://blog.kaspersky.com/raknidecryptor-vs-teslacrypt/12169/" - ] - }, - "uuid": "bd19dfff-7c8d-4c94-967e-f8ffc19e7dd9", - "value": "TeslaCrypt 3.0+" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256 + ECHD + SHA1", - "payment-method": "Bitcoin", - "ransomnotes-filenames": [ - "RECOVER<5_chars>.html", - "RECOVER<5_chars>.png", - "RECOVER<5_chars>.txt", - "_how_recover+.txt", - "_how_recover+.html", - "help_recover_instructions+.html", - "help_recover_instructions+.txt", - "help_recover_instructions+.BMP", - "_H_e_l_p_RECOVER_INSTRUCTIONS+.txt", - "_H_e_l_p_RECOVER_INSTRUCTIONS+.html", - "_H_e_l_p_RECOVER_INSTRUCTIONS+.png", - "Recovery+<5 random chars>.txt, .html, e.g., Recovery+gwote.txt", - "RESTORE_FILES_.TXT , e.g. restore_files_kksli.bmp", - "HELP_RESTORE_FILES_.TXT , e.g. help_restore_files_kksli.bmp", - "HOWTO_RECOVER_FILES_.TXT. e.g. howto_recover_files_xeyye.txt", - "HELP_TO_SAVE_FILES.txt", - "HELP_TO_SAVE_FILES.bmp" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/576600/tesladecoder-released-to-decrypt-exx-ezz-ecc-files-encrypted-by-teslacrypt/", - "http://www.welivesecurity.com/2016/05/18/eset-releases-decryptor-recent-variants-teslacrypt-ransomware/", - "https://blog.kaspersky.com/raknidecryptor-vs-teslacrypt/12169/", - "https://www.endgame.com/blog/your-package-has-been-successfully-encrypted-teslacrypt-41a-and-malware-attack-chain" - ] - }, - "uuid": "ab6b8f56-cf2d-4733-8f9c-df3d52c05e66", - "value": "TeslaCrypt 4.1A" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "ransomnotes-filenames": [ - "RECOVER<5_chars>.html", - "RECOVER<5_chars>.png", - "RECOVER<5_chars>.txt", - "_how_recover+.txt", - "_how_recover+.html", - "help_recover_instructions+.BMP", - "help_recover_instructions+.html", - "help_recover_instructions+.txt", - "_H_e_l_p_RECOVER_INSTRUCTIONS+.txt", - "_H_e_l_p_RECOVER_INSTRUCTIONS+.html", - "_H_e_l_p_RECOVER_INSTRUCTIONS+.png", - "Recovery+<5 random chars>.txt, .html, e.g., Recovery+gwote.txt", - "RESTORE_FILES_.TXT , e.g. restore_files_kksli.bmp", - "HELP_RESTORE_FILES_.TXT , e.g. help_restore_files_kksli.bmp", - "HOWTO_RECOVER_FILES_.TXT. e.g. howto_recover_files_xeyye.txt", - "HELP_TO_SAVE_FILES.txt", - "HELP_TO_SAVE_FILES.bmp" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/576600/tesladecoder-released-to-decrypt-exx-ezz-ecc-files-encrypted-by-teslacrypt/", - "http://www.welivesecurity.com/2016/05/18/eset-releases-decryptor-recent-variants-teslacrypt-ransomware/", - "https://blog.kaspersky.com/raknidecryptor-vs-teslacrypt/12169/", - "http://www.bleepingcomputer.com/news/security/teslacrypt-4-2-released-with-quite-a-few-modifications/" - ] - }, - "uuid": "eed65c12-b179-4002-a11b-7a2e2df5f0c8", - "value": "TeslaCrypt 4.2" - }, - { - "description": "Ransomware Files cannot be decrypted Has a GUI", - "meta": { - "payment-method": "Bitcoin", - "price": "1.25", - "ransomnotes-filenames": [ - "HELP_DECRYPT.HTML" - ] - }, - "uuid": "c0bce92a-63b8-4538-93dc-0911ae46596d", - "value": "Threat Finder" - }, - { - "description": "Ransomware Newer variants not decryptable. Only first 2 MB are encrypted", - "meta": { - "encryption": "AES-256 CBC for files + RSA-1024 for AES key uses LibTomCrypt", - "extensions": [ - ".Encrypted", - ".enc" - ], - "payment-method": "Bitcoin", - "price": "4.081", - "ransomnotes-filenames": [ - "HOW_TO_RESTORE_FILES.html", - "DECRYPT_INSTRUCTIONS.html", - "DESIFROVANI_POKYNY.html", - "INSTRUCCIONES_DESCIFRADO.html", - "ISTRUZIONI_DECRITTAZIONE.html", - "ENTSCHLUSSELN_HINWEISE.html", - "ONTSLEUTELINGS_INSTRUCTIES.html", - "INSTRUCTIONS_DE_DECRYPTAGE.html", - "SIFRE_COZME_TALIMATI.html", - "wie_zum_Wiederherstellen_von_Dateien.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/547708/torrentlocker-ransomware-cracked-and-decrypter-has-been-made/", - "https://twitter.com/PolarToffee/status/804008236600934403", - "http://blog.talosintelligence.com/2017/03/crypt0l0cker-torrentlocker-old-dog-new.html", - "http://id-ransomware.blogspot.ru/2016/05/torrentlocker-ransomware-aes-cbc-2048.html" - ], - "synonyms": [ - "Crypt0L0cker", - "CryptoFortress", - "Teerac" - ] - }, - "related": [ - { - "dest-uuid": "26c8b446-305c-4057-83bc-85b09630281e", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ae4aa1ef-4da0-4952-9583-9d47f84edad9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "7f6cd579-b021-4896-80da-fcc07c35c8b2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b817ce63-f1c3-49de-bd8b-fd56c3f956c9", - "value": "TorrentLocker" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Bitcoin", - "price": "100 - 150 $", - "ransomnotes-filenames": [ - "Payment_Instructions.jpg" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/618055/towerweb-ransomware-help-support-topic-payment-instructionsjpg/", - "https://id-ransomware.blogspot.com/2016/06/towerweb-ransonware-100.html" - ] - }, - "uuid": "4d470cf8-09b6-4d0e-8e5a-2f618e48c560", - "value": "TowerWeb" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".toxcrypt" - ], - "payment-method": "Bitcoin", - "price": "0.23", - "ransomnotes-filenames": [ - "tox.html" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2016/06/toxcrypt-ransomware-aes-crypto-0.html" - ] - }, - "uuid": "08fc7534-fe85-488b-92b0-630c0d91ecbe", - "value": "Toxcrypt" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".braincrypt" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "!!! HOW TO DECRYPT FILES !!!.txt" - ], - "refs": [ - "https://download.bleepingcomputer.com/demonslay335/BrainCryptDecrypter.zip", - "https://twitter.com/PolarToffee/status/811249250285842432", - "http://id-ransomware.blogspot.com/2016/12/braincrypt-ransomware.html" - ], - "synonyms": [ - "BrainCrypt" - ] - }, - "uuid": "97673387-75ae-4da4-9a5f-38773f2492e7", - "value": "Trojan" - }, - { - "description": "Ransomware May download additional malware after encryption", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".breaking_bad", - ".better_call_saul", - ".xtbl", - ".da_vinci_code", - ".windows10", - ".no_more_ransom" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "README.txt", - "nomoreransom_note_original.txt" - ], - "refs": [ - "https://www.nomoreransom.org/uploads/ShadeDecryptor_how-to_guide.pdf", - "http://www.nyxbone.com/malware/Troldesh.html", - "https://www.bleepingcomputer.com/news/security/kelihos-botnet-delivering-shade-troldesh-ransomware-with-no-more-ransom-extension/", - "https://id-ransomware.blogspot.com/2016/06/troldesh-ransomware-email.html" - ], - "synonyms": [ - "Shade", - "Troldesh" - ] - }, - "uuid": "6c3dd006-3501-4ebc-ab86-b06e4d555194", - "value": "Troldesh orShade, XTBL" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".enc" - ], - "payment-method": "Bitcoin", - "price": "0.2 (115 $)", - "refs": [ - "http://www.bleepingcomputer.com/news/security/truecrypter-ransomware-accepts-payment-in-bitcoins-or-amazon-gift-card/", - "http://id-ransomware.blogspot.com/2016/04/truecrypter-ransomware.html" - ] - }, - "uuid": "c46bfed8-7010-432a-8108-138f6d067000", - "value": "TrueCrypter" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".sifreli" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "refs": [ - "https://twitter.com/struppigel/status/821991600637313024" - ] - }, - "uuid": "132c39fc-1364-4210-aef9-48f73afc1108", - "value": "Turkish" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes-filenames": [ - "DOSYALARINIZA ULAŞMAK İÇİN AÇINIZ.html" - ], - "refs": [ - "http://www.nyxbone.com/malware/turkishRansom.html" - ] - }, - "uuid": "174dd201-0b0b-4a76-95c7-71f8141684d0", - "value": "Turkish Ransom" - }, - { - "description": "Ransomware CrypBoss Family", - "meta": { - "encryption": "AES", - "extensions": [ - "umbrecrypt_ID_[VICTIMID]" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "README_DECRYPT_UMBRE_ID_[victim_id].jpg", - "README_DECRYPT_UMBRE_ID_[victim_id].txt", - "default32643264.bmp", - "default432643264.jpg" - ], - "refs": [ - "http://www.thewindowsclub.com/emsisoft-decrypter-hydracrypt-umbrecrypt-ransomware", - "https://id-ransomware.blogspot.com/2016/06/umbrecrypt-ransomware-aes.html" - ] - }, - "uuid": "028b3489-51da-45d7-8bd0-62044e9ea49f", - "value": "UmbreCrypt" - }, - { - "description": "Ransomware", - "meta": { - "payment-method": "Website", - "price": "0.18", - "ransomnotes-filenames": [ - "Files encrypted.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/forums/t/627582/unblockupc-ransomware-help-support-topic-files-encryptedtxt/", - "http://id-ransomware.blogspot.com/2016/09/unblockupc-ransomware.html" - ] - }, - "uuid": "5a9f9ebe-f4c8-4985-8890-743f59d658fd", - "value": "UnblockUPC" - }, - { - "description": "Ransomware Ransom note instructs to use Bitmessage to get in contact with attacker - Secretishere.key - SECRETISHIDINGHEREINSIDE.KEY - secret.key", - "meta": { - "encryption": "AES", - "extensions": [ - ".H3LL", - ".0x0", - ".1999" - ], - "payment-method": "Website", - "price": "2.5", - "ransomnotes-filenames": [ - "READTHISNOW!!!.txt", - "Hellothere.txt", - "YOUGOTHACKED.TXT" - ], - "refs": [ - "http://id-ransomware.blogspot.com/2016/05/bitmessage-ransomware-aes-256-25-btc.html" - ] - }, - "uuid": "bb8c6b80-91cb-4c01-b001-7b9e73228420", - "value": "Ungluk" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".CRRRT", - ".CCCRRRPPP" - ], - "payment-method": "Website", - "ransomnotes-filenames": [ - "READ_ME_!.txt" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/839038399944224768", - "http://id-ransomware.blogspot.com/2017/02/unlock26-ransomware.html" - ] - }, - "uuid": "dfe760e5-f878-492d-91d0-05fa45a2849d", - "value": "Unlock92 " - }, - { - "description": "Ransomware CryptoWire variant", - "meta": { - "payment-method": "Bitcoin", - "price": "200 $", - "refs": [ - "https://twitter.com/struppigel/status/839771195830648833" - ] - }, - "uuid": "7799247c-4e6a-4c20-b0b3-d8e6a8ab6783", - "value": "VapeLauncher" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "uses gpg.exe", - "extensions": [ - ".vault", - ".xort", - ".trun" - ], - "payment-method": "Bitcoin", - "price": "0.438", - "ransomnotes-filenames": [ - "VAULT.txt", - "xort.txt", - "trun.txt", - ".hta | VAULT.hta" - ], - "refs": [ - "http://www.nyxbone.com/malware/russianRansom.html" - ], - "synonyms": [ - "CrypVault", - "Zlader" - ] - }, - "related": [ - { - "dest-uuid": "2195387d-ad9c-47e6-8f14-a49388b26eab", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "63a82b7f-9a71-47a8-9a79-14acc6595da5", - "value": "VaultCrypt" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".VBRANSOM" - ], - "payment-method": "Website (onion)", - "refs": [ - "https://twitter.com/BleepinComputer/status/817851339078336513" - ] - }, - "uuid": "44a56cd0-8cd8-486f-972d-4b1b416e9077", - "value": "VBRANSOM 7" - }, - { - "description": "Ransomware Based on EDA2", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".Venusf", - ".Venusp" - ], - "payment-method": "Bitcoin", - "price": "0.15 (100 $)", - "ransomnotes-filenames": [ - "ReadMe.txt" - ], - "refs": [ - "https://blog.malwarebytes.com/threat-analysis/2016/08/venus-locker-another-net-ransomware/?utm_source=twitter&utm_medium=social", - "http://www.nyxbone.com/malware/venusLocker.html", - "https://id-ransomware.blogspot.com/2016/08/venuslocker-ransomware-aes-256.html" - ] - }, - "uuid": "7340c6d6-a16e-4a01-8bb4-8ad3edc64d28", - "value": "VenusLocker" - }, - { - "description": "Ransomware Polymorphism / Self-replication", - "meta": { - "extensions": [ - ".exe" - ], - "payment-method": "Bitcoin", - "price": "250 $", - "refs": [ - "http://www.nyxbone.com/malware/Virlock.html", - "http://www.welivesecurity.com/2014/12/22/win32virlock-first-self-reproducing-ransomware-also-shape-shifter/" - ], - "synonyms": [ - "NSMF" - ] - }, - "uuid": "5c736959-6c58-4bf2-b084-7197b42e500a", - "value": "Virlock" - }, - { - "description": "Ransomware", - "meta": { - "encryption": "AES-256", - "extensions": [ - ".CrySiS", - ".xtbl", - ".crypt", - ".DHARMA", - ".id-########.decryptformoney@india.com.xtbl", - ".[email_address].DHARMA" - ], - "payment-method": "Bitcoin", - "price": "2.5 - 3", - "ransomnotes-filenames": [ - "How to decrypt your data.txt" - ], - "refs": [ - "http://www.welivesecurity.com/2016/11/24/new-decryption-tool-crysis-ransomware/", - "http://media.kaspersky.com/utilities/VirusUtilities/EN/rakhnidecryptor.zip", - "http://www.nyxbone.com/malware/virus-encoder.html", - "http://blog.trendmicro.com/trendlabs-security-intelligence/crysis-targeting-businesses-in-australia-new-zealand-via-brute-forced-rdps/" - ], - "synonyms": [ - "CrySiS" - ] - }, - "uuid": "15a30d84-4f5f-4b75-a162-e36107d30215", - "value": "Virus-Encoder" - }, - { - "description": "Ransomware Zyklon variant", - "meta": { - "extensions": [ - ".wflx" - ], - "payment-method": "Bitcoin", - "price": "299 $", - "ransomnotes-filenames": [ - "HOW_TO_UNLOCK_FILES_README_().txt" - ], - "refs": [ - "https://labs.opendns.com/2016/07/13/wildfire-ransomware-gaining-momentum/", - "https://id-ransomware.blogspot.com/2016/06/wildfire-locker-ransomware-aes-256-cbc.html" - ], - "synonyms": [ - "Hades Locker" - ] - }, - "related": [ - { - "dest-uuid": "c0091a62-b1cd-495d-898b-d2f3b5af601e", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "31945e7b-a734-4333-9ea2-e52051ca015a", - "value": "WildFire Locker" - }, - { - "description": "Ransomware encrypted files will still have the original non-encrypted header of 0x33 bytes length", - "meta": { - "encryption": "XOR or TEA", - "extensions": [ - ".EnCiPhErEd", - ".73i87A", - ".p5tkjw", - ".PoAr2w", - ".fileiscryptedhard", - ".encoderpass", - ".zc3791", - ".antihacker2017", - "....PAY_IN_MAXIM_24_HOURS_OR_ALL_YOUR_FILES_WILL_BE_PERMANENTLY_DELETED_PLEASE_BE_REZONABLE_you_have_only_1_single_chance_YOU_NEED_TO_PURCHASE_THE_DECRYPTOR_FROM_US_FAST_AND_URGENT" - ], - "payment-method": "Bitcoin", - "price": "0.8", - "ransomnotes-filenames": [ - "HOW TO DECRYPT FILES.TXT" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/Dfj9G_2XkAE0ZS2.jpg", - "https://pbs.twimg.com/media/Dfj9H66WkAEHazN.jpg" - ], - "refs": [ - "https://support.kaspersky.com/viruses/disinfection/2911", - "https://decrypter.emsisoft.com/xorist", - "https://twitter.com/siri_urz/status/1006833669447839745", - "https://id-ransomware.blogspot.com/2016/06/xrtn-ransomware-rsa-1024-gnu-privacy.html" - ] - }, - "uuid": "0a15a920-9876-4985-9d3d-bb0794722258", - "value": "Xorist" - }, - { - "description": "Ransomware VaultCrypt family", - "meta": { - "extensions": [ - ".xrtn" - ] - }, - "uuid": "22ff9f8c-f658-46cc-a404-1a54e1b74569", - "value": "XRTN " - }, - { - "description": "Ransomware Attempt to steal passwords", - "meta": { - "extensions": [ - ".Locked" - ], - "payment-method": "Bitcoin", - "price": "0.25", - "refs": [ - "https://twitter.com/malwrhunterteam/status/808280549802418181" - ] - }, - "uuid": "0810ea3e-1cd6-4ea3-a416-5895fb685c5b", - "value": "You Have Been Hacked!!!" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".zcrypt" - ], - "payment-method": "Bitcoin", - "price": "1.2 - 5", - "refs": [ - "https://blogs.technet.microsoft.com/mmpc/2016/05/26/link-lnk-to-ransom/", - "http://id-ransomware.blogspot.com/2016/05/zcrypt-ransomware-rsa-2048-email.html" - ], - "synonyms": [ - "Zcryptor" - ] - }, - "uuid": "7eed5e96-0219-4355-9a9c-44643272894c", - "value": "Zcrypt" - }, - { - "description": "Ransomware mpritsken@priest.com", - "meta": { - "extensions": [ - ".crypto" - ], - "payment-method": "Bitcoin", - "price": "3", - "ransomnotes-filenames": [ - "how.txt" - ], - "refs": [ - "http://www.bleepingcomputer.com/forums/t/617874/zimbra-ransomware-written-in-python-help-and-support-topic-crypto-howtotxt/", - "https://id-ransomware.blogspot.com/2016/06/zimbra-ransomware-aes-optzimbrastore.html" - ] - }, - "uuid": "07346620-a0b4-48d5-9158-5048741f5078", - "value": "Zimbra" - }, - { - "description": "Ransomware VaultCrypt family", - "meta": { - "encryption": "RSA", - "extensions": [ - ".vault" - ], - "payment-method": "Bitcoin", - "price": "100 - 900 $", - "refs": [ - "http://www.nyxbone.com/malware/russianRansom.html" - ], - "synonyms": [ - "Russian", - "VaultCrypt", - "CrypVault" - ] - }, - "related": [ - { - "dest-uuid": "63a82b7f-9a71-47a8-9a79-14acc6595da5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "2195387d-ad9c-47e6-8f14-a49388b26eab", - "value": "Zlader" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".zorro" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "Take_Seriously (Your saving grace).txt" - ], - "refs": [ - "https://twitter.com/BleepinComputer/status/844538370323812353", - "http://id-ransomware.blogspot.com/2017/03/zorro-ransomware.html" - ] - }, - "uuid": "b2bd25e1-d41c-42f2-8971-ecceceb6ba08", - "value": "Zorro" - }, - { - "description": "Ransomware Hidden Tear family, GNL Locker variant", - "meta": { - "extensions": [ - ".zyklon" - ], - "payment-method": "Euro", - "price": "250", - "refs": [ - "http://id-ransomware.blogspot.com/2016/05/zyklon-locker-ransomware-windows-250.html" - ], - "synonyms": [ - "GNL Locker", - "Zyklon Locker" - ] - }, - "related": [ - { - "dest-uuid": "390abe30-8b9e-439e-a6d3-2ee978f05fba", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "721e9af0-8a60-4b9e-9137-c23e86d75722", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "78ef77ac-a570-4fb9-af80-d04c09dff9ab", - "value": "Zyklon" - }, - { - "description": "Ransomware", - "meta": { - "extensions": [ - ".vxLock" - ], - "payment-method": "Bitcoin", - "price": "0.3", - "refs": [ - "https://id-ransomware.blogspot.com/2017/01/vxlock-ransomware.html" - ] - }, - "uuid": "37950a1c-0035-49e0-9278-e878df0a10f3", - "value": "vxLock" - }, - { - "description": "We recently observed several large scale email campaigns that were attempting to distribute a new variant of ransomware that has been dubbed \"Jaff\". Interestingly we identified several characteristics that we have previously observed being used during Dridex and Locky campaigns. In a short period of time, we observed multiple campaigns featuring high volumes of malicious spam emails being distributed, each using a PDF attachment with an embedded Microsoft Word document functioning as the initial downloader for the Jaff ransomware.", - "meta": { - "encryption": "AES", - "extensions": [ - ".jaff" - ], - "payment-method": "Bitcoin", - "price": "1.82 - 2.036", - "ransomnotes-filenames": [ - "WallpapeR.bmp", - "ReadMe.bmp", - "ReadMe.html", - "ReadMe.txt" - ], - "refs": [ - "http://blog.talosintelligence.com/2017/05/jaff-ransomware.html", - "https://www.bleepingcomputer.com/news/security/jaff-ransomware-distributed-via-necurs-malspam-and-asking-for-a-3-700-ransom/", - "http://id-ransomware.blogspot.com/2017/05/jaff-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "2c51a717-726b-4813-9fcc-1265694b128e", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "8e3d44d0-6768-4b54-88b0-2e004a7f2297", - "value": "Jaff" - }, - { - "description": "Using EternalBlue SMB Exploit To Infect Victims", - "meta": { - "encryption": "may be a mixture of AES and RC4.", - "extensions": [ - "._[10_digit_victim_id].UIWIX" - ], - "payment-method": "Bitcoin", - "price": "0.122", - "ransomnotes-filenames": [ - "DECODE_FILES.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/uiwix-ransomware-using-eternalblue-smb-exploit-to-infect-victims/", - "http://id-ransomware.blogspot.com/2017/05/uiwix-ransomware.html" - ], - "synonyms": [ - "UIWIX" - ] - }, - "uuid": "369d6fda-0284-44aa-9e74-f6651416fec4", - "value": "Uiwix Ransomware" - }, - { - "description": "Fileless, Code-injecting Ransomware", - "meta": { - "extensions": [ - ".pr0tect" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "http://blog.trendmicro.com/trendlabs-security-intelligence/files/2017/06/SOREBRECT-3.jpg" - ], - "refs": [ - "http://blog.trendmicro.com/trendlabs-security-intelligence/analyzing-fileless-code-injecting-sorebrect-ransomware/" - ] - }, - "uuid": "34cedaf0-b1f0-4b5d-b7bd-2eadfc630ea7", - "value": "SOREBRECT" - }, - { - "description": "claims it detected \"Children Pornsites\" in your browser history", - "meta": { - "extensions": [ - ".CYRON" - ], - "payment-method": "PaySafeCard", - "price": "50 €", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2017/august/25/DHvA8CDWAAIR5er.jpg" - ], - "refs": [ - "https://twitter.com/struppigel/status/899524853426008064", - "https://id-ransomware.blogspot.com/2017/08/cyron-ransomware.html" - ] - }, - "uuid": "f597d388-886e-46d6-a5cc-26deeb4674f2", - "value": "Cyron" - }, - { - "description": "Made with OXAR builder; decryptable", - "meta": { - "extensions": [ - ".OXR" - ], - "payment-method": "Bitcoin Email", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2017/august/25/DHvDae7XoAE9usO[1].jpg" - ], - "refs": [ - "https://twitter.com/struppigel/status/899528477824700416" - ] - }, - "uuid": "3330e226-b71a-4ee4-8612-2b06b58368fc", - "value": "Kappa" - }, - { - "description": "CyberSplitter variant", - "meta": { - "extensions": [ - ".Isis" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2017/august/25/DHvM552WsAAuDbi[1].jpg" - ], - "refs": [ - "https://twitter.com/struppigel/status/899537940539478016" - ] - }, - "uuid": "1fe6c23b-863e-49e4-9439-aa9e999aa2e1", - "value": "Trojan Dz" - }, - { - "description": "ransomware written by self proclaimed script kiddies that should really be considered trollware", - "meta": { - "extensions": [ - ".xolzsec" - ], - "payment-method": "no ransom", - "refs": [ - "https://twitter.com/struppigel/status/899916577252028416", - "http://id-ransomware.blogspot.com/2017/08/xolzsec-ransomware.html" - ] - }, - "uuid": "f2930308-2e4d-4af5-b119-746be0fe7f2c", - "value": "Xolzsec" - }, - { - "description": "HiddenTear variant; decryptable", - "meta": { - "extensions": [ - ".flat" - ], - "payment-method": "Bitcoin", - "price": "250 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2017/august/25/DH5KChhXsAADOIu[1].jpg" - ], - "refs": [ - "https://twitter.com/struppigel/status/900238572409823232", - "https://id-ransomware.blogspot.com/2017/08/flatchestware-ransomware.html" - ] - }, - "uuid": "d29341fd-f48e-4caa-8a28-b17853b779d1", - "value": "FlatChestWare" - }, - { - "description": "The ransomware does not use a customized desktop wallpaper to signal its presence, and the only way to discover that SynAck has infected your PC is by the ransom notes dropped on the user's desktop, named in the format: RESTORE_INFO-[id].txt. For example: RESTORE_INFO-4ABFA0EF.txt\n In addition, SynAck also appends its own extension at the end of all files it encrypted. This file extensions format is ten random alpha characters for each file. For example: test.jpg.XbMiJQiuoh. Experts believe the group behind SynAck uses RDP brute-force attacks to access remote computers and manually download and install the ransomware.", - "meta": { - "payment-method": "Bitcoin", - "price": "2 100 $", - "ransomnotes-filenames": [ - "RESTORE_INFO-[id].txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/synack-ransomware-sees-huge-spike-in-activity/", - "https://www.bleepingcomputer.com/news/security/synack-ransomware-uses-process-doppelg-nging-technique/", - "https://id-ransomware.blogspot.com/2017/09/synack-ransomware.html" - ], - "synonyms": [ - "Syn Ack" - ] - }, - "related": [ - { - "dest-uuid": "a396a0bb-6dc5-424a-bdbd-f8ba808ca2c2", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "04585cd8-54ae-420f-9191-8ddb9b88a80c", - "value": "SynAck" - }, - { - "description": "A new ransomware called SyncCrypt was discovered by Emsisoft security researcher xXToffeeXx that is being distributed by spam attachments containing WSF files. When installed these attachments will encrypt a computer and append the .kk extension to encrypted files.", - "meta": { - "extensions": [ - ".kk" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes-filenames": [ - "readme.html", - "readme.png" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/synccrypt-ransomware-hides-inside-jpg-files-appends-kk-extension/", - "http://id-ransomware.blogspot.com/2017/08/synccrypt-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "e717a26d-17aa-4cd7-88de-dc75aa365232", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "83d10b83-9038-4dd6-b305-f14c21478588", - "value": "SyncCrypt" - }, - { - "description": "On October 24, 2017, Cisco Talos was alerted to a widescale ransomware campaign affecting organizations across eastern Europe and Russia. As was the case in previous situations, we quickly mobilized to assess the situation and ensure that customers remain protected from this and other threats as they emerge across the threat landscape. There have been several large scale ransomware campaigns over the last several months. This appears to have some similarities to Nyetya in that it is also based on Petya ransomware. Major portions of the code appear to have been rewritten. The distribution does not appear to have the sophistication of the supply chain attacks we have seen recently.", - "meta": { - "encryption": "AES+RSA", - "payment-method": "Bitcoin", - "price": "0.05 (300 $)", - "ransomnotes": [ - "https://www.welivesecurity.com/wp-content/uploads/2017/10/mbr_cut.png" - ], - "refs": [ - "http://blog.talosintelligence.com/2017/10/bad-rabbit.html", - "https://id-ransomware.blogspot.com/2017/10/badrabbit-ransomware.html", - "https://www.welivesecurity.com/2017/10/24/bad-rabbit-not-petya-back/", - "https://securelist.com/bad-rabbit-ransomware/82851/", - "http://www.intezer.com/notpetya-returns-bad-rabbit/" - ], - "synonyms": [ - "BadRabbit", - "Bad-Rabbit" - ] - }, - "related": [ - { - "dest-uuid": "6f736038-4f74-435b-8904-6870ee0e23ba", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00c31914-bc0e-11e8-8241-3ff3b5e4671d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "e8af6388-6575-4812-94a8-9df1567294c5", - "value": "Bad Rabbit" - }, - { - "description": "A malware author by the name of Luc1F3R is peddling a new ransomware strain called Halloware for the lowly price of $40. Based on evidence gathered by Bleeping Computer, Luc1F3R started selling his ransomware this week, beginning Thursday.", - "meta": { - "extensions": [ - "(Lucifer) [prepend]" - ], - "payment-method": "Bitcoin", - "price": "150 $", - "refs": [ - "https://www.bleepingcomputer.com/news/security/halloware-ransomware-on-sale-on-the-dark-web-for-only-40/", - "http://id-ransomware.blogspot.com/2017/11/halloware-ransomware.html" - ] - }, - "uuid": "b366627d-dbc0-45ba-90bc-5f5694f45e35", - "value": "Halloware" - }, - { - "description": "Recently BleepingComputer has received a flurry of support requests for a new ransomware being named StorageCrypt that is targeting NAS devices such as the Western Digital My Cloud. Victims have been reporting that their files have been encrypted and a note left with a ransom demand of between .4 and 2 bitcoins to get their files back. User's have also reported that each share on their NAS device contains a Autorun.inf file and a Windows executable named 美女与野兽.exe, which translates to Beauty and the beast. From the samples BleepingComputer has received, this Autorun.inf is an attempt to spread the 美女与野兽.exe file to other computers that open the folders on the NAS devices.", - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Bitcoin", - "price": "0.2 - 0.4 - 2", - "ransomnotes": [ - "Warning\n\nYour documents, photos,databases,important files have been encrypted by RSA-4096 and AES-256!\nIf you modify any file, it may cause make you cannot decrypt!!!\n\nDon't waste your precious time to try decrypt the files.\nIf there is no key that we provide to you , NO ONE can decrypt your precious files, even Jesus.\n\nHow to decrypt your files ?\n\nYou have to pay for decryption in bitcoin\nTo decrypt your files,please following the steps below\n\n1,Pay 2.0 bitcoin to this address: [bitcoin_address]\n\nPay To : [bitcoin_address]\nAmount : 2.0\n\n2,After you have finished paying,Contact us and Send us your Decrypt-ID via email\n\n3,Once we have confimed your deal,You can use the tool we sent to you to decrypt all your files.\n\nHow to obtain bitcoin ?\n\nThe easiest way to buy bitcoin is LocalBitcoins site.\nYou have to register, click Buy bitcoins and select the seller\nby payment method and price\n\nhttps://localbitcoins.com/buy_bitcoins\n\nhttps://paxful.com/buy-bitcoin\n\nhttp://bitcointalk.org/\n\n If you have any questions please do not hesitate to contact us\n\nContact Email:JeanRenoAParis@protonmail.com\n\nDecrypt-ID:" - ], - "ransomnotes-filenames": [ - "_READ_ME_FOR_DECRYPT.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/storagecrypt-ransomware-infecting-nas-devices-using-sambacry/", - "https://id-ransomware.blogspot.com/2017/11/storagecrypter.html" - ] - }, - "uuid": "0b920d03-971f-413c-8057-60d187192140", - "value": "StorageCrypt" - }, - { - "description": "A new ransomware called HC7 is infecting victims by hacking into Windows computers that are running publicly accessible Remote Desktop services. Once the developers gain access to the hacked computer, the HC7 ransomware is then installed on all accessible computers on the network.\nOriginally released as HC6, victims began posting about it in the BleepingComputer forums towards the end of November. As this is a Python-to-exe executable, once the script was extracted ID Ransomware creator Michael Gillespie was able determine that it was decryptable and released a decryptor.\nUnfortunately, a few days later, the ransomware developers released a new version called HC7 that was not decryptable. Thi sis because they removed the hard coded encryption key and instead switched to inputting the key as a command line argument when the attackers run the ransomware executable. Thankfully, there may be a way to get around that as well so that victims can recover their keys.", - "meta": { - "extensions": [ - ".GOTYA" - ], - "payment-method": "Bitcoin", - "price": "500 - 700 $", - "ransomnotes": [ - "ALL YOUR FILES WERE ENCRYPTED.\nTO RESTORE THIS FILE, YOU MUST SEND $700 BTC for MASCHINE\nOR $5,000 BTC FOR ALL NETWORK\nADDRESS: 15aM71TGtRZRrY97vdGcDEZeJYBWZhf4FP\nAFTER PAYMENT SENT EMAIL m4zn0v@keemail.me\nALONG WITH YOUR IDENTITY: VVNFUi1QQzA5\nNOT TO TURN OFF YOUR COMPUTER, UNLESS IT WILL BREAK" - ], - "ransomnotes-filenames": [ - "RECOVERY.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/hc7-gotya-ransomware-installed-via-remote-desktop-services-spread-with-psexec/", - "https://id-ransomware.blogspot.com/2017/12/hc7-ransomware.html" - ] - }, - "uuid": "9325e097-9fea-490c-9b89-c2d40c166101", - "value": "HC7" - }, - { - "description": "Predecessor of HC7", - "meta": { - "extensions": [ - ".fucku" - ], - "payment-method": "Bitcoin", - "price": "2 500 $", - "refs": [ - "https://twitter.com/demonslay335/status/935622942737817601?ref_src=twsrc%5Etfw", - "https://www.bleepingcomputer.com/news/security/hc7-gotya-ransomware-installed-via-remote-desktop-services-spread-with-psexec/", - "http://id-ransomware.blogspot.com/2017/11/hc6-ransomware.html" - ] - }, - "uuid": "909fde65-e015-40a9-9012-8d3ef62bba53", - "value": "HC6" - }, - { - "description": "Security researchers have discovered a new ransomware strain named qkG that targets only Office documents for encryption and infects the Word default document template to propagate to new Word documents opened through the same Office suite on the same computer.", - "meta": { - "payment-method": "Bitcoin", - "price": "300 $", - "refs": [ - "https://www.bleepingcomputer.com/news/security/qkg-ransomware-encrypts-only-word-documents-hides-and-spreads-via-macros/", - "http://id-ransomware.blogspot.com/2017/11/qkg-ransomware.html" - ], - "synonyms": [ - "QkG" - ] - }, - "uuid": "1f3eab7f-da0a-4e0b-8a9f-cda2f146c819", - "value": "qkG" - }, - { - "description": "The Scarab ransomware is a relatively new ransomware strain that was first spotted by security researcher Michael Gillespie in June this year.\nWritten in Delphi, the first version was simplistic and was recognizable via the \".scarab\" extension it appended after the names of encrypted files.\nMalwarebytes researcher Marcelo Rivera spotted a second version in July that used the \".scorpio\" extension. The version spotted with the Necurs spam today has reverted back to using the .scarab extension.\nThe current version of Scarab encrypts files but does not change original file names as previous versions. This Scarab version appends each file's name with the \".[suupport@protonmail.com].scarab\" extension.\nScarab also deletes shadow volume copies and drops a ransom note named \"IF YOU WANT TO GET ALL YOUR FILES BACK, PLEASE READ THIS.TXT\" on users' computers, which it opens immediately.", - "meta": { - "extensions": [ - ".scarab", - ".scorpio", - ".[suupport@protonmail.com].scarab", - ".fastrecovery@airmail.cc", - ".files-xmail@cock.li.TXT", - ".leen", - ".qweuirtksd", - ".mammon", - ".omerta", - ".bomber", - ".CRYPTO", - ".lolita", - ".stevenseagal@airmail.cc", - ".lol", - ".crypted034", - ".ironhead" - ], - "payment-method": "Bitcoin Email", - "ransomnotes": [ - "Attention: if you do not have money then you do not need to write to us!\nThe file is encrypted with the RSA-2048 algorithm, only we can decrypt the file.\n====================================================================================================\n fastrecovery@airmail.cc\n====================================================================================================\nYour files are encrypted!\nYour personal identifier:\n[redacted hex]\n====================================================================================================\nTo decrypt files, please contact us by email:\nfastrecovery@airmail.cc\n====================================================================================================\nThe file is encrypted with the RSA-2048 algorithm, only we can decrypt the file.\nAttention: if you do not have money then you do not need to write to us!", - "Your files are now encrypted!\n\nYour personal identifier:\n[redacted hex]\n\nAll your files have been encrypted due to a security problem with your PC.\n\nNow you should send us email with your personal identifier.\nThis email will be as confirmation you are ready to pay for decryption key.\nYou have to pay for decryption in Bitcoins. The price depends on how fast you write to us.\nAfter payment we will send you the decryption tool that will decrypt all your files.\n\nContact us using this email address: mr.leen@protonmail.com\n\nFree decryption as guarantee!\nBefore paying you can send us up to 3 files for free decryption.\nThe total size of files must be less than 10Mb (non archived), and files should not contain\nvaluable information (databases, backups, large excel sheets, etc.).\n\nHow to obtain Bitcoins?\n * The easiest way to buy bitcoins is LocalBitcoins site. You have to register, click\n 'Buy bitcoins', and select the seller by payment method and price:\n https://localbitcoins.com/buy_bitcoins\n * Also you can find other places to buy Bitcoins and beginners guide here:\n http://www.coindesk.com/information/how-can-i-buy-bitcoins\n\nAttention! \n * Do not rename encrypted files.\n * Do not try to decrypt your data using third party software, it may cause permanent data loss.\n * Decryption of your files with the help of third parties may cause increased price\n (they add their fee to our) or you can become a victim of a scam.", - "Attention, all your files are encrypted with the AES cbc-128 algorithm!\n \nIt's not a virus like WannaCry and others, I hacked your computer,\nThe encryption key and bitcoin wallet are unique to your computer,\nso you are guaranteed to be able to return your files.\n \nBut before you pay, you can make sure that I can really decrypt any of your files.\n \nTo do this, send me several encrypted files to cyrill.fedor0v@yandex.com, a maximum of 5 megabytes each, I will decrypt them\nand I will send you back. No more than 5 files. Do not forget to send in the letter bitcoin address 1BhHZxek7iUTm1mdrgax6yVrPzViqLhr9u from this file.\n \nAfter that, pay the decryption in the amount of 500$ to the bitcoin address: 1BhHZxek7iUTm1mdrgax6yVrPzViqLhr9u\nAfter payment, send me a letter to cyrill.fedor0v@yandex.com with payment notification.\nOnce payment is confirmed, I will send you a decryption program.\n \nYou can pay bitcoins online in many ways:\nhttps://buy.blockexplorer.com/ - payment by bank card\nhttps://www.buybitcoinworldwide.com/\nhttps://localbitcoins.net\n \nAbout Bitcoins:\nhttps://en.wikipedia.org/wiki/Bitcoin\n\n If you have any questions, write to me at cyrill.fedor0v@yandex.com\n \nAs a bonus, I will tell you how hacked your computer is and how to protect it in the future." - ], - "ransomnotes-filenames": [ - "IF YOU WANT TO GET ALL YOUR FILES BACK, PLEASE READ THIS.TXT", - "HOW TO RECOVER ENCRYPTED FILES-fastrecovery@airmail.cc.TXT", - "HOW TO RECOVER ENCRYPTED FILES.TXT", - "INSTRUCTIONS FOR RESTORING FILES.TXT", - "!!!ReadMeToDecrypt.txt", - "_How to restore files.TXT", - "How to restore encrypted files.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/september/14/Scarab-ransomware.jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsnFZrGX4AE2H1c[1].jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/30/Ds8PMFpW0AIcYuJ[1].jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/december/7/DtzAAIAW0AEHC86[1].jpg", - "https://pbs.twimg.com/media/DuC07vPWkAAMekP.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/scarab-ransomware-pushed-via-massive-spam-campaign/", - "https://labsblog.f-secure.com/2017/11/23/necurs-business-is-booming-in-a-new-partnership-with-scarab-ransomware/", - "https://blogs.forcepoint.com/security-labs/massive-email-campaign-spreads-scarab-ransomware", - "https://twitter.com/malwrhunterteam/status/933643147766321152", - "https://myonlinesecurity.co.uk/necurs-botnet-malspam-delivering-a-new-ransomware-via-fake-scanner-copier-messages/", - "https://twitter.com/demonslay335/status/1006222754385924096", - "https://twitter.com/demonslay335/status/1006908267862396928", - "https://twitter.com/demonslay335/status/1007694117449682945", - "https://twitter.com/demonslay335/status/1049316344183836672", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/", - "https://twitter.com/Amigo_A_/status/1039105453735784448", - "https://twitter.com/GrujaRS/status/1072057088019496960", - "http://id-ransomware.blogspot.com/2017/06/scarab-ransomware.html" - ] - }, - "uuid": "cf8fbd03-4510-41cc-bec3-712fa7609aa4", - "value": "Scarab" - }, - { - "description": "A new ransomware called File Spider is being distributed through spam that targets victims in Bosnia and Herzegovina, Serbia, and Croatia. These spam emails contains malicious Word documents that will download and install the File Spider ransomware onto a victims computer.File Spider is currently being distributed through malspam that appears to be targeting countries such as Croatia, Bosnia and Herzegovina, and Serbia. The spam start with subjects like\"Potrazivanje dugovanja\", which translates to \"Debt Collection\" and whose message, according to Google Translate, appear to be in Serbian.", - "meta": { - "extensions": [ - ".spider" - ], - "payment-method": "Bitcoin", - "price": "0.00725", - "ransomnotes": [ - "As you may have already noticed, all your important files are encrypted and you no longer have access to them. A unique key has been generated specifically for this PC and two very strong encryption algorithm was applied in that process. Original content of your files are wiped and overwritten with encrypted data so it cannot be recovered using any conventional data recovery tool.\n\nThe good news is that there is still a chance to recover your files, you just need to have the right key.\n\nTo obtain the key, visit our website from the menu above. You have to be fast, after 96 hours the key will be blocked and all your files will remain permanently encrypted since no one will be able to recover them without the key!\n\nRemember, do not try anything stupid, the program has several security measures to delete all your files and cause the damage to your PC.\n\nTo avoid any misunderstanding, please read Help section." - ], - "ransomnotes-filenames": [ - "HOW TO DECRYPT FILES.url" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/file-spider-ransomware-targeting-the-balkans-with-malspam/", - "http://id-ransomware.blogspot.com/2017/12/file-spider-ransomware.html" - ], - "synonyms": [ - "Spider" - ] - }, - "uuid": "3e75ce6b-b6de-4e5a-9501-8f9f847c819c", - "value": "File Spider" - }, - { - "description": "A barely functional piece of macOS ransomware, written in Swift.", - "meta": { - "date": "Febuary 2017", - "payment-method": "Bitcoin", - "price": "0.25", - "refs": [ - "https://objective-see.com/blog/blog_0x25.html#FileCoder" - ], - "synonyms": [ - "FindZip", - "Patcher" - ] - }, - "related": [ - { - "dest-uuid": "e211ea8d-5042-48ae-86c6-15186d1f8dba", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "bad1057c-4f92-4747-a0ec-31bcc062dab8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "091c9923-5939-4bde-9db5-56abfb51f1a2", - "value": "FileCoder" - }, - { - "description": "A basic piece of macOS ransomware, offered via a 'malware-as-a-service' model.", - "meta": { - "date": "June 2017", - "payment-method": "Bitcoin", - "price": "0.25 (700 $)", - "refs": [ - "https://objective-see.com/blog/blog_0x25.html" - ] - }, - "related": [ - { - "dest-uuid": "66862f1a-5823-4a9a-bd80-439aaafc1d8b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "7574c7f1-5075-4230-aca9-d6c0956f1fac", - "value": "MacRansom" - }, - { - "description": "A new ransomware called GandCrab was released towards the end of last week that is currently being distributed via exploit kits. GandCrab has some interesting features not seen before in a ransomware, such as being the first to accept the DASH currency and the first to utilize the Namecoin powered .BIT tld. ", - "meta": { - "date": "January 2018", - "extensions": [ - ".Crab", - ".CRAB" - ], - "payment-method": "Dash", - "price": "1 - 3", - "ransomnotes": [ - "---= GANDCRAB =---\n\nAttention!\nAll your files documents, photos, databases and other important files are encrypted and have the extension: .GDCB \nThe only method of recovering files is to purchase a private key. It is on our server and only we can recover your files.\nThe server with your key is in a closed network TOR. You can get there by the following ways:\n1. Download Tor browser - https://www.torproject.org/\n2. Install Tor browser\n3. Open Tor Browser\n4. Open link in tor browser:http://gdcbghvjyqy7jclk.onion/[id]\n5. Follow the instructions on this page\n\nIf Tor/Tor browser is locked in your country or you can not install it, open one of the following links in your regular browser:\n1. http://gdcbghvjyqy7jclk.onion.top/[id]\n2. http://gdcbghvjyqy7jclk.onion.casa/[id]\n3. http://gdcbghvjyqy7jclk.onion.guide/[id]\n4. http://gdcbghvjyqy7jclk.onion.rip/[id]\n5. http://gdcbghvjyqy7jclk.onion.plus/[id]\n\nOn our page you will see instructions on payment and get the opportunity to decrypt 1 file for free.\n\nDANGEROUS!\nDo not try to modify files or use your own private key - this will result in the loss of your data forever!", - "---= GANDCRAB =---\nAttention!\nAll your files documents, photos, databases and other important files are encrypted and have the extension: .GDCB\nThe only method of recovering files is to purchase a private key. It is on our server and only we can recover your files.\nThe server with your key is in a closed network TOR. You can get there by the following ways:\n1. Download Tor browser - https://www.torproject.org/\n2. Install Tor browser\n3. Open Tor Browser\n4. Open link in tor browser: http://gdcbmuveqjsli57x.onion/[id]\n5. Follow the instructions on this page\nOn our page you will see instructions on payment and get the opportunity to decrypt 1 file for free.\nIf you can't download TOR and use it, or in your country TOR blocked, read it:\n1. Visit https://tox.chat/download.html\n2. Download and install qTOX on your PC.\n3. Open it, click \"New Profile\" and create profile.\n4. Search our contact - 6C5AD4057E594E090E0C987B3089F74335DA75F04B7403E0575663C26134956917D193B195A5\n5. In message please write your ID and wait our answer: 6361f798c4ba3647\nDANGEROUS!\nDo not try to modify files or use your own private key - this will result in the loss of your data forever!", - "ENCRYPTED BY GANDCRAB 3\n\nDEAR [user_name],\n\nYOUR FILES ARE UNDER STRONG PROTECTION BY OUR SOFTWARE. IN ORDER TO RESTORE IT YOU MUST BUY DECRYPTOR\n\nFor further steps read CRAB-DECRYPT.txt that is located in every encrypted folder.", - " ---= GANDCRAB V3 =--- \n\nAttention! \n\nAll your files documents, photos, databases and other important files are encrypted and have the extension: .CRAB \n\nThe only method of recovering files is to purchase a private key. It is on our server and only we can recover your files. \n\n\nThe server with your key is in a closed network TOR. You can get there by the following ways: \n\n0. Download Tor browser - https://www.torproject.org/ \n\n1. Install Tor browser \n\n2. Open Tor Browser \n\n3. Open link in TOR browser: http://gandcrab2pie73et.onion/[id] \n\n4. Follow the instructions on this page \n\nOn our page you will see instructions on payment and get the opportunity to decrypt 1 file for free. \n\n\nThe alternative way to contact us is to use Jabber messanger. Read how to:\n0. Download Psi-Plus Jabber Client: https://psi-im.org/download/\n1. Register new account: http://sj.ms/register.php\n0) Enter \"username\": [id]\n1) Enter \"password\": your password\n2. Add new account in Psi\n3. Add and write Jabber ID: ransomware@sj.ms any message\n4. Follow instruction bot \n\nATTENTION!\nIt is a bot! It's fully automated artificial system without human control!\nTo contact us use TOR links. We can provide you all required proofs of decryption availibility anytime. We are open to conversations.\nYou can read instructions how to install and use jabber here http://www.sfu.ca/jabber/Psi_Jabber_PC.pdf \n\nCAUGHTION! \n\nDo not try to modify files or use your own private key. This will result in the loss of your data forever! " - ], - "ransomnotes-filenames": [ - "GDCB-DECRYPT.txt", - "CRAB-Decrypt.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/g/gandcrab/v3/desktop-background.jpg", - "https://www.bleepstatic.com/images/news/security/f/fallout-exploit-kit/gandcrab-fallout.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/gandcrab-ransomware-distributed-by-exploit-kits-appends-gdcb-extension/", - "https://www.bleepingcomputer.com/news/security/gandcrab-ransomware-being-distributed-via-malspam-disguised-as-receipts/", - "https://www.bleepingcomputer.com/news/security/gandcrab-ransomware-version-2-released-with-new-crab-extension-and-other-changes/", - "https://www.bleepingcomputer.com/news/security/gandcrab-version-3-released-with-autorun-feature-and-desktop-background/", - "https://www.bleepingcomputer.com/news/security/new-fallout-exploit-kit-drops-gandcrab-ransomware-or-redirects-to-pups/", - "https://www.bleepingcomputer.com/news/security/gandcrab-v5-ransomware-utilizing-the-alpc-task-scheduler-exploit/", - "https://id-ransomware.blogspot.com/2018/01/gandcrab-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "1f05f646-5af6-4a95-825b-164f49616aa4", - "tags": [ - "estimative-language:likelihood-probability=\"almost-certain\"" - ], - "type": "dropped-by" - } - ], - "uuid": "5920464b-e093-4fa0-a275-438dffef228f", - "value": "GandCrab" - }, - { - "description": "Security researchers uncovered a new ransomware named ShurL0ckr (detected by Trend Micro as RANSOM_GOSHIFR.B) that reportedly bypasses detection mechanisms of cloud platforms. Like Cerber and Satan, ShurL0ckr’s operators further monetize the ransomware by peddling it as a turnkey service to fellow cybercriminals, allowing them to earn additional income through a commission from each victim who pays the ransom.", - "meta": { - "date": "Febuary 2018", - "payment-method": "Bitcoin", - "price": "0.01 - 0.1", - "refs": [ - "https://www.trendmicro.com/vinfo/us/security/news/cybercrime-and-digital-threats/shurl0ckr-ransomware-as-a-service-peddled-on-dark-web-can-reportedly-bypass-cloud-applications" - ] - }, - "uuid": "cc7f6da3-fafd-444f-b7e9-f0e650fb4d4f", - "value": "ShurL0ckr" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2018", - "extensions": [ - ".fairytail" - ], - "payment-method": "Bitcoin", - "refs": [ - "https://sensorstechforum.com/fr/fairytail-files-virus-cryakl-ransomware-remove-restore-data/", - "https://www.technologynews.tech/cryakl-ransomware-virus", - "http://www.zdnet.com/article/cryakl-ransomware-decryption-keys-now-available-for-free/" - ] - }, - "related": [ - { - "dest-uuid": "3c51fc0e-42d8-4ff0-b1bd-5c8c20271a39", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "32fa6c53-b4fc-47f8-894c-1ea74180e02f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "4f3e494e-0e37-4894-94b2-741a8100f07a", - "value": "Cryakl" - }, - { - "description": "first ransomware seen to ask for payment to be made in Bitcoin Cash (BCH)", - "meta": { - "extensions": [ - ".THANATOS" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "refs": [ - "https://mobile.twitter.com/EclecticIQ/status/968478323889332226", - "https://www.eclecticiq.com/resources/thanatos--ransomware-first-ransomware-ask-payment-bitcoin-cash?type=intel-report", - "http://id-ransomware.blogspot.com/2018/02/thanatos-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "24fabbe0-27a2-4c93-a6a6-c14767efaa25", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "361d7a90-2fde-4fc7-91ed-fdce26eb790f", - "value": "Thanatos" - }, - { - "description": "RSAUtil is distributed by the developer hacking into remote desktop services and uploading a package of files. This package contains a variety of tools, a config file that determines how the ransomware executes, and the ransomware itself.", - "meta": { - "payment-method": "Bitcoin", - "price": "750 $", - "ransomnotes": [ - "Hello... :)\nFor instructions on how to recovery the files, write to me:\njonskuper578@india.com\njonskuper578@gmx.de\njonskuper578@protonmail.com\nIn the letter, indicate your personal ID (see the file format).\nIf you have not received an answer, write to me again.", - "WARNING!!!\nYour ID 83624883\nOUR FILES ARE DECRIPTED\nYour documents, photos, database, save games and other important data was encrypted.\nData recovery the necessary interpreter. To get the interpreter, should send an email to helppme@india.com or hepl1112@aol.com.\nIn a letter to include Your personal ID (see the beginning of this document).\nIn response to the letter You will receive the address of your Bitcoin wallet to which you want to perform the transfer.\nWhen money transfer is confirmed, You will receive the decrypter file for Your computer.\nAfter starting the programm-interpreter, all Your files will be restored.\nAttention! Do not attempt to remove a program or run the anti-virus tools.", - "ПРЕДУПРЕЖДЕНИЕ!!!\nВаш ID 83624883\nOUR FILES ARE DECRIPTED\nЗашифрованы ваши документы, фотографии, база данных, сохранения игр и другие важные данные.\nВосстановить данные нужен интерпретатор. Для получения интерпретатора надо отправить email на helppme@india.com или hepl1112@aol.com.\nВ письме укажите Ваш личный ID (см. начало этого документа).\nВ ответ на письмо Вы получите адрес вашего биткойн-кошелька, на который Вы хотите сделать перевод.\nКогда денежный перевод будет подтвержден, вы получите файл-декриптер для Вашего компьютера.\nПосле запуска программы-интерпретатора все Ваши файлы будут восстановлены.\nВнимание! Не пытайтесь удалить программу или запустить антивирусные программы.", - "Hello…\nFor instructions on how to recovery the files, write to me:\nvine77725@gmx.de\nvine77725@india.com\nvine77725@protonmail.com\nIn the letter, indicate your personal ID (see the file format).\nIf you have not received an answer, write to me again.", - "Привет мой друг!\nВсе файлы на твоем ПК зашифрованы!\nМой email: helppme@india.com или\nhepl1112@aol.com", - "Hello my friend!\nAll files on your PC encryphted!\nmy email: helppme@india.com or\nhepl1112@aol.com" - ], - "ransomnotes-filenames": [ - "How_return_files.txt", - "Image.jpg" - ], - "ransomnotes-refs": [ - "https://4.bp.blogspot.com/-6jE-GW6wCr8/WQY1L_uHsFI/AAAAAAAAE-A/3YR0bwwBJqgp8CsApZq4F_44JkMB0m2WwCLcB/s320/image-note.jpg", - "https://2.bp.blogspot.com/-T4lvnNISc_A/WQY1SI1r1mI/AAAAAAAAE-E/tH7p02nS2LUTvXmq66poiyM1RYhHc4HbwCLcB/s200/lock-note.jpg" - ], - "refs": [ - "https://www.securityweek.com/rsautil-ransomware-distributed-rdp-attacks", - "https://www.bleepingcomputer.com/news/security/rsautil-ransomware-helppme-india-com-installed-via-hacked-remote-desktop-services/", - "http://id-ransomware.blogspot.lu/2017/04/rsautil-ransomware.html", - "http://id-ransomware.blogspot.lu/2017/04/" - ], - "synonyms": [ - "Vagger", - "DONTSLIP" - ] - }, - "uuid": "f80b0a42-21ef-11e8-8ac7-0317408794e2", - "value": "RSAUtil" - }, - { - "description": "A new ransomware has been discovered that utilizes the legitimate GnuPG, or GPG, encryption program to encrypt a victim's files. Currently in the wild, this ransomware is called Qwerty Ransomware and will encrypt a victims files, overwrite the originals, and the append the .qwerty extension to an encrypted file's name.", - "meta": { - "payment-method": "Bitcoin", - "ransomnotes": [ - "Your computer is encrypted . Mail cryz1@protonmail.com . Send your ID 5612.\nNote! You have only 72 hours for write on e-mail (see below) or all your files will be lost!" - ], - "ransomnotes-filenames": [ - "README_DECRYPT.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/qwerty-ransomware-utilizes-gnupg-to-encrypt-a-victims-files/" - ] - }, - "uuid": "15c370c0-2799-11e8-a959-57cdcd57e3bf", - "value": "Qwerty Ransomware" - }, - { - "description": "A new ransomware was discovered this week by MalwareHunterTeam called Zenis Ransomware. While it is currently unknown how Zenis is being distributed, multiple victims have already become infected with this ransomware. What is most disturbing about Zenis is that it not encrypts your files, but also purposely deletes your backups.", - "meta": { - "payment-method": "Bitcoin Email (Tor)", - "ransomnotes": [ - "*** All your files has been encrypted ***\n\nI am ZENIS. A mischievous boy who loves cryptography, hardware and programming. My world is full of unanswered questions and puzzles half and half, and I'm coming to discover a new world. A world in digital space that you are supposed to play the role of my toys.\n\nIf you want to win in this game, you have to listen carefully to my instructions, otherwise you will be caught up in a one-step game and you will become the main loser of the story.\n\nMy instructions are simple and clear. Then follow these steps:\n\n1. Send this file (Zenis-Instructions.html) to my email with one your encrypted file less than 2 MB to trust to the game.\n\n2. I decrypt your file for free and send for you.\n\n3. If you confirm the correctness of the files, verify that the files are correct via email\n\n4. Then receive the price of decrypting files\n\n5. After you have deposited, please send me the payment details\n\n6. After i confirm deposit, i send you the \"Zenis Decryptor\" along with \"Private Key\" to recovery all your files.\n\nNow you can finish the game. You won the game. congratulations.\n\n\nPlease submit your request to both emails:\n\nTheZenis@Tutanota.com\n\nTheZenis@MailFence.com\n\nIf you did not receive an email after six hours, submit your request to the following emails:\n\nTheZenis@Protonmail.com\n\nTheZenis@Mail2Tor.com (On the TOR network)\n\n\nWarning: 3rd party and public programs, It may cause irreversible damage to your files. And your files will be lost forever." - ], - "ransomnotes-filenames": [ - "Zenis-Instructions.html" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/zenis-ransomware-encrypts-your-data-and-deletes-your-backups/", - "https://id-ransomware.blogspot.com/2018/03/zenis-ransomware.html" - ] - }, - "uuid": "cbe3ee70-2d11-11e8-84bb-9b3c525a48d9", - "value": "Zenis Ransomware" - }, - { - "meta": { - "payment-method": "Dollars", - "price": "199", - "refs": [ - "https://www.bleepingcomputer.com/news/security/author-of-polski-vortex-and-flotera-ransomware-families-arrested-in-poland/", - "http://id-ransomware.blogspot.com/2017/03/flotera-ransomware.html" - ] - }, - "uuid": "aab356ac-396c-11e8-90c8-631229f19d7a", - "value": "Flotera Ransomware" - }, - { - "description": "A new ransomware was discovered this week by MalwareHunterTeam called Black Ruby. This ransomware will encrypt the files on a computer, scramble the file name, and then append the BlackRuby extension. To make matters worse, Black Ruby will also install a Monero miner on the computer that utilizes as much of the CPU as it can. Discovered on February 6, 2018. May have been distributed through unknown vectors. Will not encrypt a machine if its IP address is identified as coming from Iran; this feature enables actors to avoid a particular Iranian cybercrime law that prohibits Iran-based actors from attacking Iranian victims. Encrypts files on the infected machine, scrambles files, and appends the .BlackRuby extension to them. Installs a Monero miner on the infected computer that utilizes the machine’s maximum CPU power. Delivers a ransom note in English asking for US$650 in Bitcoins. Might be installed via Remote Desktop Services.", - "meta": { - "extensions": [ - ".BlackRuby" - ], - "payment-method": "Monero miner on the computer", - "ransomnotes": [ - " ____ __ __ ____ __\n / __ ) / /____ _ _____ / /__ / __ \\ __ __ / /_ __ __\n / __ |/ // __ `// ___// //_/ / /_/ // / / // __ \\ / / / /\n / /_/ // // /_/ // /__ / ,< / _, _// /_/ // /_/ // /_/ /\n /_____//_/ \\__,_/ \\___//_/|_| /_/ |_| \\__,_//_.___/ \\__, /\n /____/\n\n===================== Identification Key =====================\n\n[id]\n\n===================== Identification Key =====================\n\n[Can not access your files?]\n\nCongratulations, you are now part of our family #BlackRuby Ransomware. The range of this family is wider and bigger every day.\nOur hosts welcome our presence because we will give them a scant souvenir from the heart of Earth.\n\nThis time, we are guest with a new souvenir called \"Black Ruby\". A ruby ​​in black, different, beautiful, and brilliant, which has been bothered to extract those years and you must also endure this hard work to keep it. If you do not have the patience of this difficulty or you hate some of this precious stone, we are willing to receive the price years of mining and finding rubies for your relief and other people of the world who are guests of the black ruby.\n\nSo let's talk a little bit with you without a metaphor and literary terms to understand the importance of the subject.\nIt does not matter if you're a small business or you manage a large organization, no matter whether you are a regular user or a committed employee, it's important that you have a black ruby and to get rid of it, you need to get back to previous situation and we need a next step.\n\nThe breadth of this family is not supposed to stop, because we have enough knowledge and you also trust our knowledge.\nWe are always your backers and guardian of your information at this multi-day banquet and be sure that no one in the world can take it from you except for us who extracts this precious stone. We need a two-sided cooperation in developing cybersecurity knowledge. The background to this cooperation is a mutual trust, which will result in peace and tranquility. you must pay $650 (USD) worth of Bitcoins for restore your system to the previous state and you are free to choose to stay in this situation or return to the normal.\n\nDo not forget that your opportunity is limited. From these limits you can create golden situations. Be sure we will help you in this way and to know that having a black ruby does not always mean riches. You and your system are poor, poor knowledge of cybersecurity and lack of security on your system!.\n\n ========================================================================================================================\n\n [HOW TO DECRYPT FILES]\n\n 1. Copy \"Identification Key\".\n 2. Send this key with two encrypted files (less than 5 MB) for trust us to email address \"TheBlackRuby@Protonmail.com\".\n 3. We decrypt your two files and send them to your email.\n 4. After ensuring the integrity of the files, you must pay $650 (USD) with bitcoin and send transaction code to our email, our bitcoin address is \"19S7k3zHphKiYr85T25FnqdxizHcgmjoj1\".\n 5. You get \"Black Ruby Decryptor\" Along with the private key of your system.\n 6. Everything returns to the normal and your files will bereleased.\n\n========================================================================================================================\n\n[What is encryption?]\n\nEncryption is a reversible modification of information for security reasons but providing full access to it for authorised users.\n To become an authorised user and keep the modification absolutely reversible (in other words to have a possibility to decrypt your files) you should have an \"Personal Identification Key\". But not only it. It is required also to have the special decryption software\n(in your case “Black Ruby Decryptor” software) for safe and complete decryption of all your files and data.\n\n[Everything is clear for me but what should I do?]\n\n The first step is reading these instructions to the end. Your files have been encrypted with the “Black Ruby Ransomware” software; the instructions (“HOW-TO-DECRYPT-FILES.txt”) in the folders with your encrypted files are not viruses, they will help you. After reading this text the most part of people start searching in the Internet the words the “Black Ruby Ransomware” where they find a lot of ideas, recommendation and instructions. It is necessary to realise that we are the ones who closed the lock on your files and we are the only ones who have this secret key to open them.\n\n[Have you got advice?]\n\n[*** Any attempts to get back you files with the third-party tools can be fatal for your encrypted files ***]\nThe most part of the tried-party software change data with the encrypted files to restore it but this cases damage to the files. \nFinally it will be impossible to decrypt your files. When you make a puzzle but some items are lost, broken or not put in its place - the puzzle items will never match, the same way the third-party software will ruin your files completely and irreversibly. You should realise that any intervention of the third-party software to restore files encrypted with the “Black Ruby Ransomware” software may be fatal for your files.\n\nIf you look through this text in the Internet and realise that something is wrong with your files but you do not have any instructions to restore your files, please contact your antivirus support." - ], - "ransomnotes-filenames": [ - "HOW-TO-DECRYPT-FILES.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/black-ruby-ransomware-skips-victims-in-iran-and-adds-a-miner-for-good-measure/", - "https://www.accenture.com/t20180803T064557Z__w__/us-en/_acnmedia/PDF-83/Accenture-Cyber-Threatscape-Report-2018.pdf" - ], - "synonyms": [ - "BlackRuby" - ] - }, - "uuid": "abf3001c-396c-11e8-8da6-ef501eef12e1", - "value": "Black Ruby" - }, - { - "description": "A new ransomware has been discovered by MalwareHunterTeam that is based off of the InfiniteTear ransomware family, of which BlackRuby and Zenis are members. When this ransomware infects a computer it will encrypt the files, scramble the filenames, and append the .WHITEROSE extension to them.", - "meta": { - "extensions": [ - ".WHITEROSE", - "_ENCRYPTED_BY.WHITEROSE" - ], - "payment-method": "Website Tor", - "ransomnotes": [ - "[Rose ASCII art]\n\n[WhiteRose written in ASCII art]\n\nThe singing of the sparrows, the breezes of the northern mountains and smell of the earth that was raining in the morning filled the entire garden space. I'm sitting on a wooden chair next to a bush tree, I have a readable book in my hands and I am sweating my spring with a cup of bitter coffee. Today is a different day.\n\nBehind me is an empty house of dreams and in front of me, full of beautiful white roses. To my left is an empty blue pool of red fish and my right, trees full of spring white blooms.\n\n I drink coffee, I'll continue to read a book from William Faulkner. In the garden environment, peace and quiet. My life always goes that way. Always alone without even an intimate friend.\n\nI have neither a pet, nor a friend or an enemy; I am a normal person with fantastic wishes among the hordes of white rose flowers. Everything is natural. I'm just a little interested in hacking and programming. My only electronic devices in this big garden are an old laptop for do projects and an iPhone for check out the news feeds for malware analytics on Twitter without likes posts.\n\nBelieve me, my only assets are the white roses of this garden. I think of days and write at night: the story, poem, code, exploit or the accumulation of the number of white roses sold and I say to myself that the wealth is having different friends of different races, languages, habits and religions, Not only being in a fairly stylish garden with full of original white roses.\n\nToday, I think deeply about the decision that has involved my mind for several weeks. A decision to freedom and at the worth of unity, intimacy, joy and love and is the decision to release white roses and to give gifts to all peoples of the world.\n\nI do not think about selling white roses again. This time, I will plant all the white roses of the garden to bring a different gift for the people of each country. No matter where is my garden and where I am from, no matter if you are a housekeeper or a big company owner, it does not matter if you are the west of the world or its east, it's important that the white roses are endless and infinite. You do not need to send letters or e-mails to get these roses. Just wait it tomorrow. Wait for good days with White Rose.\n\nI hope you accept this gift from me and if it reaches you, close your eyes and place yourself in a large garden on a wooden chair and feel this beautiful scene to reduce your anxiety and everyday tension.\n\nThank you for trusting me. Now open your eyes. Your system has a flower like a small garden; A white rose flower.\n\n/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n[Recovery Instructions]\n\n I. Download qTox on your computer from [https://tox.chat/download.html]\nII. Create new profile then enter our ID in search contacts\n Our Tox ID: \"6F548F217897AA4140FB4C514C8187F2FFDBA3CAFC83795DEE2FBCA369E689006B7CED4A18E9\". III. Wait for us to accept your request.\nIV. Copy '[PersonalKey]' in \"HOW-TO-RECOVERY-FILES.TXT\" file and send this key with one encrypted file less size then 2MB for trust us in our Tox chat.\n IV.I. Only if you did not receive a reply after 24 hours from us, send your message to our secure tor email address \"TheWhiteRose@Torbox3uiot6wchz.onion\".\n IV.II. For perform \"Step IV.I\" and enter the TOR network, you must download tor and register in \"http://torbox3uiot6wchz.onion\" Mail Service)\nV. We decrypt your two files and we will send you.\nVI. After ensuring the integrity of the files, We will send you payment info.\nVII. Now after payment, you get \"WhiteRose Decryptor\" Along with the private key of your system.\nVIII.Everything returns to the normal and your files will be released.\n\n/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nWhat is encryption?\n\n In cryptography, encryption is the process of encoding a message or information in such a way that only authorized parties can access it, and those who are not authorized cannot. Encryption does not itself prevent interference, but denies the intelligible content to a would-be interceptor. In an encryption scheme, the intended information or message, referred to as plaintext, is encrypted using an encryption algorithm – a cipher – generating ciphertext that can be read only if decrypted. For technical reasons, an encryption scheme usually uses a pseudo-random encryption key generated by an algorithm. It is in principle possible to decrypt the message without possessing the key, but, for a well-designed encryption scheme, considerable computational resources and skills are required. An authorized recipient can easily decrypt the message with the key provided by the originator to recipients but not to unauthorized users. in your case “WhiteRose Decryptor” software for safe and complete decryption of all your files and data.\n\nAny other way?\n\nIf you look through this text in the Internet and realise that something is wrong with your files but you do not have any instructions to restore your files, please contact your antivirus support." - ], - "ransomnotes-filenames": [ - "HOW-TO-RECOVERY-FILES.TXT" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-whiterose-ransomware-is-decryptable-and-tells-a-strange-story/", - "http://id-ransomware.blogspot.com/2018/03/whiterose-ransomware.html" - ] - }, - "uuid": "abc80362-396c-11e8-bc5c-8bca89c0f797", - "value": "WhiteRose" - }, - { - "description": "In what could only be a joke, a new ransomware has been discovered called \"PUBG Ransomware\" that will decrypt your files if you play the game called PlayerUnknown's Battlegrounds. Discovered by MalwareHunterTeam, when the PUBG Ransomware is launched it will encrypt a user's files and folders on the user's desktop and append the .PUBG extension to them. When it has finished encrypting the files, it will display a screen giving you two methods that you can use to decrypt the encrypted files.", - "meta": { - "extensions": [ - ".PUBG" - ], - "payment-method": "Game", - "price": "Play to decrypt", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/p/pubg-ransomware/pubg-ransomware.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/pubg-ransomware-decrypts-your-files-if-you-play-playerunknowns-battlegrounds/", - "https://id-ransomware.blogspot.com/2018/04/pubg-ransomware.html" - ] - }, - "uuid": "2239b3ca-3c9b-11e8-873e-53608d51ee71", - "value": "PUBG Ransomware" - }, - { - "description": "LockCrypt is an example of yet another simple ransomware created and used by unsophisticated attackers. Its authors ignored well-known guidelines about the proper use of cryptography. The internal structure of the application is also unprofessional. Sloppy, unprofessional code is pretty commonplace when ransomware is created for manual distribution. Authors don’t take much time preparing the attack or the payload. Instead, they’re rather focused on a fast and easy gain, rather than on creating something for the long run. Because of this, they could easily be defeated.", - "meta": { - "extensions": [ - ".BadNews" - ], - "payment-method": "Bitcoin", - "price": "0.5 - 1", - "ransomnotes-filenames": [ - "How To Decode Files.hta" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/august/31/DlsLwUjXsAA0xyY[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/lockcrypt-ransomware-cracked-due-to-bad-crypto/", - "https://twitter.com/malwrhunterteam/status/1034436350748053504", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/", - "http://id-ransomware.blogspot.com/2017/06/lockcrypt-ransomware.html" - ] - }, - "uuid": "ac070e9a-3cbe-11e8-9f9d-839e888f2340", - "value": "LockCrypt" - }, - { - "description": "Magniber is a new ransomware being distributed by the Magnitude Exploit Kit that appears to be the successor to the Cerber Ransomware. While many aspects of the Magniber Ransomware are different than Cerber, the payment system and the files it encrypts are very similar.", - "meta": { - "extensions": [ - ".ihsdj", - ".kgpvwnr", - ".ndpyhss" - ], - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes": [ - " ALL Y0UR D0CUMENTS, PHOTOS, DATABASES AND OTHER IMP0RTANT FILES HAVE BEEN ENCRYPTED!\n ====================================================================================================\n Your files are NOT damaged! Your files are modified only. This modification is reversible.\n\n The only 1 way to decrypt your files is to receive the private key and decryption program.\n\n Any attempts to restore your files with the third-party software will be fatal for your files!\n ====================================================================================================\n To receive the private key and decryption program follow the instructions below:\n\n 1. Download \"Tor Browser\" from https://www.torproject.org/ and install it.\n\n 2. In the \"Tor Browser\" open your personal page here:\n\n\n http://[victim_id].ofotqrmsrdc6c3rz.onion/EP866p5M93wDS513\n\n\n Note! This page is available via \"Tor Browser\" only.\n ====================================================================================================\n Also you can use temporary addresses on your personal page without using \"Tor Browser\":\n\n\n http://[victim_id].bankme.date/EP866p5M93wDS513\n\n http://[victim_id].jobsnot.services/EP866p5M93wDS513\n\n http://[victim_id].carefit.agency/EP866p5M93wDS513\n\n http://[victim_id].hotdisk.world/EP866p5M93wDS513\n\n\n Note! These are temporary addresses! They will be available for a limited amount of time!" - ], - "ransomnotes-filenames": [ - "READ_ME_FOR_DECRYPT_[id].txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/decrypters-for-some-versions-of-magniber-ransomware-released/", - "https://www.bleepingcomputer.com/news/security/goodbye-cerber-hello-magniber-ransomware/", - "https://twitter.com/demonslay335/status/1005133410501787648", - "http://id-ransomware.blogspot.com/2017/10/my-decryptor-ransomware.html" - ] - }, - "uuid": "a0c1790a-3ee7-11e8-9774-93351d675a9e", - "value": "Magniber Ransomware" - }, - { - "meta": { - "extensions": [ - ".improved" - ], - "payment-method": "Bitcoin", - "price": "10 000 $", - "ransomnotes": [ - "UNCRYPT.README" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/april/6/vurten.jpg" - ], - "refs": [ - "https://twitter.com/siri_urz/status/981191281195044867", - "http://id-ransomware.blogspot.com/2018/04/vurten-ransomware.html" - ] - }, - "uuid": "7666e948-3f09-11e8-b0b2-af79c067d856", - "value": "Vurten" - }, - { - "description": "A ransomware family that targets users from certain countries or regions. It locks the computer and displays a location-specific webpage that covers the desktop and demands that the user pay a fine for the supposed possession of illicit material. The Reveton ransomware is one of the first screen-locking ransomware strains, and it appeared when Bitcoin was still in its infancy, and before it became the cryptocurrency of choice in all ransomware operations. Instead, Reveton operators asked victims to buy GreenDot MoneyPak vouchers, take the code on the voucher and enter it in the Reveton screen locker.", - "meta": { - "payment-method": "Bitcoin", - "price": "200 $", - "refs": [ - "https://www.bleepingcomputer.com/news/security/microsoft-engineer-charged-in-reveton-ransomware-case/", - "https://en.wikipedia.org/wiki/Ransomware#Reveton", - "https://nakedsecurity.sophos.com/2012/08/29/reveton-ransomware-exposed-explained-and-eliminated/" - ] - }, - "uuid": "1912ec68-4145-11e8-ac06-9b6643035a71", - "value": "Reveton ransomware" - }, - { - "description": "Fusob is one of the major mobile ransomware families. Between April 2015 and March 2016, about 56 percent of accounted mobile ransomware was Fusob.\nLike a typical mobile ransomware, it employs scare tactics to extort people to pay a ransom. The program pretends to be an accusatory authority, demanding the victim to pay a fine from $100 to $200 USD or otherwise face a fictitious charge. Rather surprisingly, Fusob suggests using iTunes gift cards for payment. Also, a timer clicking down on the screen adds to the users’ anxiety as well.\nIn order to infect devices, Fusob masquerades as a pornographic video player. Thus, victims, thinking it is harmless, unwittingly download Fusob.\nWhen Fusob is installed, it first checks the language used in the device. If it uses Russian or certain Eastern European languages, Fusob does nothing. Otherwise, it proceeds on to lock the device and demand ransom. Among victims, about 40% of them are in Germany with the United Kingdom and the United States following with 14.5% and 11.4% respectively.\nFusob has lots in common with Small, which is another major family of mobile ransomware. They represented over 93% of mobile ransomwares between 2015 and 2016.", - "meta": { - "payment-method": "Bitcoin", - "price": "100 - 200 $", - "refs": [ - "https://en.wikipedia.org/wiki/Ransomware#Fusob" - ] - }, - "uuid": "c921d9ac-4145-11e8-965b-df5002d4cad8", - "value": "Fusob" - }, - { - "meta": { - "extensions": [ - ".FUCK" - ], - "ransomnotes": [ - "What Happened to My Computer?\nYour important files are encrypted.\nMany of your documents, photos, videos, databases and other files are no longer accessible because they have been encrypted. Maybe you are busy looking for a way to recover your files, but do not waste your time. Nobody can recover your files without our decryption service.\n\nCan I Recover My Files?\nSure. We guarantee that you can recover all your files safely and easily. But you have not so enough time.\nBut if you want to decrypt all your files, you need to pay.\n\nHow Do I Pay?\nPayment is accepted in Bitcoin only.\nPlease check the current price of Bitcoin and buy some bitcoins.\nAnd send the correct amount to the address specified in this window.\n\nWe strongly recommend you to not remove this software, and disable your anti-virus for a while, until you pay and the payment gets processed. If your anti-virus gets updated and removes this software automatically, it will not be able to recover your files even if you pay!\nOnce the payment is sent, send us an e-mail to the specified address specifying your \"Client ID\", you will be sent your decryption key in return.\nHow to buy Bitcoins?\n\nStep 1 : Create a portfolio on the Blockchain website at the address : https://blockchain.info/fr/wallet/#/signup\nStep 2 : Sign in to your account you just created and purchase the amount shown : https://blockchain.info/wallet/#/buy-sell\n Step 3 : Send the amount to the indicated Bitcoin address, once this is done send us an email with your \"Client ID\" you can retreive this in the file \"instruction.txt\" or \"Whats Appens With My File.s.txt\" in order to ask us the key of decryption of your data.\n\nContact us at : spaghetih@protonmail.com\nSend 20$ to Bitcoin at 1MFA4PEuDoe2UCKgabrwm8P4KztASKtiuv if you want decrypt your files !\nYour Client ID is : [id]" - ], - "ransomnotes-refs": [ - "https://pastebin.com/xkRaRytW" - ], - "refs": [ - "https://twitter.com/demonslay335/status/981270787905720320" - ] - }, - "uuid": "b0ce2b90-4171-11e8-af82-0f4431fd2726", - "value": "OXAR" - }, - { - "meta": { - "payment-method": "Bitcoin", - "price": "100 $", - "refs": [ - "http://id-ransomware.blogspot.com/2018/03/bansomqarewanna-ransomware.html" - ] - }, - "uuid": "b95a76d8-4171-11e8-b9b3-1bf62ec3265e", - "value": "BansomQare Manna Ransomware" - }, - { - "uuid": "60e79876-4178-11e8-8c04-63662c94ba03", - "value": "Haxerboi Ransomware" - }, - { - "meta": { - "payment-method": "Bitcoin Email", - "refs": [ - "https://twitter.com/malwrhunterteam/status/982229994364547073", - "http://id-ransomware.blogspot.com/2018/04/skyfile-ransomware.html" - ] - }, - "uuid": "b4654c94-417a-11e8-8c2c-5b5748496f92", - "value": "SkyFile" - }, - { - "description": "Supposed joke ransomware, decrypt when running an exectable with the string \"Minecraft\"", - "meta": { - "payment-method": "Game", - "refs": [ - "https://www.bleepingcomputer.com/news/security/minecraft-and-cs-go-ransomware-strive-for-media-attention/" - ] - }, - "uuid": "443c55c6-43d1-11e8-9072-6fdcf89aa4e6", - "value": "MC Ransomware" - }, - { - "description": "Supposed joke ransomware, decrypt when running an exectable with the string \"csgo\"", - "meta": { - "payment-method": "Game", - "price": "Play during 5 hours", - "refs": [ - "https://www.bleepingcomputer.com/news/security/minecraft-and-cs-go-ransomware-strive-for-media-attention/" - ] - }, - "uuid": "449e18b0-43d1-11e8-847e-0fed641732a1", - "value": "CSGO Ransomware" - }, - { - "meta": { - "extensions": [ - ".Encrypted[BaYuCheng@yeah.net].XiaBa", - ".XiaoBa1", - ".XiaoBa2", - ".XiaoBa3", - ".XiaoBa4", - ".XiaoBa5", - ".XiaoBa6", - ".XiaoBa7", - ".XiaoBa8", - ".XiaoBa9", - ".XiaoBa10", - ".XiaoBa11", - ".XiaoBa12", - ".XiaoBa13", - ".XiaoBa14", - ".XiaoBa15", - ".XiaoBa16", - ".XiaoBa17", - ".XiaoBa18", - ".XiaoBa19", - ".XiaoBa20", - ".XiaoBa21", - ".XiaoBa22", - ".XiaoBa23", - ".XiaoBa24", - ".XiaoBa25", - ".XiaoBa26", - ".XiaoBa27", - ".XiaoBa28", - ".XiaoBa29", - ".XiaoBa30", - ".XiaoBa31", - ".XiaoBa32", - ".XiaoBa33", - ".XiaoBa34", - ".AdolfHitler" - ], - "payment-method": "Bitcoin", - "price": "1 200 yuan (180,81 $)", - "ransomnotes-filenames": [ - "_@XiaoBa@_.bmp", - "_@Explanation@_.hta", - "_XiaoBa_Info_.hta", - "_XiaoBa_Info_.bmp", - "# # DECRYPT MY FILE # #.bmp" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/DNIoIFuX4AAce7J.jpg", - "https://pbs.twimg.com/media/DNx5Of-X0AASVda.jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/8/De8WvF_X0AARtYr[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/xiaoba-ransomware-retooled-as-coinminer-but-manages-to-ruin-your-files-anyway/", - "https://twitter.com/malwrhunterteam/status/923847744137154560", - "https://twitter.com/struppigel/status/926748937477939200", - "https://twitter.com/demonslay335/status/968552114787151873", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/", - "https://twitter.com/malwrhunterteam/status/1004048636530094081", - "https://id-ransomware.blogspot.com/2017/10/xiaoba-ransomware.html" - ] - }, - "uuid": "ef094aa6-4465-11e8-81ce-739cce28650b", - "value": "XiaoBa ransomware" - }, - { - "description": "The NMCRYPT Ransomware is a generic file encryption Trojan that was detected in the middle of April 2018. The NMCRYPT Ransomware is a file encoder Trojan that is designed to make data unreadable and convince users to pay a fee for unlocking content on the infected computers. The NMCRYPT Ransomware is nearly identical to hundreds of variants of the HiddenTear open-source ransomware and compromised users are unable to use the Shadow Volume snapshots made by Windows to recover. Unfortunately, the NMCRYPT Ransomware disables the native recovery features on Windows, and you need third-party applications to rebuild your data.", - "meta": { - "date": "April 2018", - "encryption": "AES+RSA", - "extensions": [ - ".NMCRYPT" - ], - "payment-method": "Bitcoin", - "price": "7000 $", - "ransomnotes": [ - "Encrypted files! All your files are encrypted. Using AES256-bit encryption and RSA-2048-bit encryption. Making it impossible to recover files without the correct private key. If you are interested in getting is the key and recover your files You should proceed with the following steps. The only way to decrypt your files safely is to buy the Descrypt and Private Key software. Any attempts to restore your files with the third-party software will be fatal for your files! Important use Firefox or Chrome browser To proceed with the purchase you must access one of the link below https://lylh3uqyzay3lhrd.onion.to/ https://lylh3uqyzay3lhrd.onion.link/ If neither of the links is online for a long period of time, there is another way to open it, you should install the Tor Browser..." - ], - "ransomnotes-refs": [ - "https://sensorstechforum.com/wp-content/uploads/2018/04/stf-NMCRYPT-ransomware-virus-ransom-note-tor-onion-network-page-768x827.png" - ], - "refs": [ - "https://sensorstechforum.com/nmcrypt-files-ransomware-virus-remove-restore-data/", - "https://www.enigmasoftware.com/nmcryptansomware-removal/" - ] - }, - "uuid": "bd71be69-fb8c-4b1f-9d96-993ab23d5f2b", - "value": "NMCRYPT Ransomware" - }, - { - "description": "It is currently unknown if Iron is indeed a new variant by the same creators of Maktub, or if it was simply inspired by the latter, by copying the design for the payment portal for example.\nWe know the Iron ransomware has mimicked at least three ransomware families:Maktub (payment portal design)\nDMA Locker (Iron Unlocker, decryption tool)\nSatan (exclusion list)", - "meta": { - "payment-method": "Bitcoin", - "price": "0.2", - "ransomnotes": [ - "We’re very sorry that all of your personal files have been encrypted :( But there are good news – they aren’t gone, you still have the opportunity to restore them! Statistically, the lifespan of a hard-drive is anywhere from 3 to 5 years. If you don’t make copies of important information, you could lose everything! Just imagine! In order to receive the program that will decrypt all of your files, you will need to pay a certain amount. But let’s start with something else…" - ], - "ransomnotes-filenames": [ - "!HELP_YOUR_FILES.HTML" - ], - "refs": [ - "https://bartblaze.blogspot.lu/2018/04/maktub-ransomware-possibly-rebranded-as.html", - "http://id-ransomware.blogspot.com/2018/04/ironlocker-ransomware.html" - ] - }, - "uuid": "ba64d47c-46cd-11e8-87df-ff6252b4ea76", - "value": "Iron" - }, - { - "meta": { - "extensions": [ - ".tron" - ], - "payment-method": "Bitcoin", - "price": "0.007305 - 0.05", - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/DavxIr-W4AEq3Ny.jpg" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/985152346773696512", - "http://id-ransomware.blogspot.com/2018/04/tron-ransomware.html" - ] - }, - "uuid": "94290f1c-46ff-11e8-b9c6-ef8852c58952", - "value": "Tron ransomware" - }, - { - "description": "A new in-development ransomware was discovered that has an interesting characteristic. Instead of the distributed executable performing the ransomware functionality, the executables compiles an embedded encrypted C# program at runtime and launches it directly into memory.", - "meta": { - "extensions": [ - "sequre@tuta.io_[hex]" - ], - "payment-method": "Bitcoin", - "price": "0.14", - "ransomnotes-filenames": [ - "HOW DECRIPT FILES.hta" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/c/compiled-ransomware/ransom-note.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/new-c-ransomware-compiles-itself-at-runtime/" - ] - }, - "uuid": "c1788ac0-4fa0-11e8-b0fd-63f5a2914926", - "value": "Unnamed ramsomware 1" - }, - { - "description": "Attackers are targeting Internet accessible HPE iLO 4 remote management interfaces, supposedly encrypting the hard drives, and then demanding Bitcoins to get access to the data again.\nAccording to the victim, the attackers are demanding 2 bitcoins to gain access to the drives again. The attackers will also provide a bitcoin address to the victim that should be used for payment. These bitcoin addresses appear to be unique per victim as the victim's was different from other reported ones.\nAn interesting part of the ransom note is that the attackers state that the ransom price is not negotiable unless the victim's are from Russia. This is common for Russian based attackers, who in many cases tries to avoid infecting Russian victims.\nFinally, could this be a decoy/wiper rather than an actual true ransomware attack? Ransomware attacks typically provide a unique ID to the victim in order to distinguish one victim from another. This prevents a victim from \"stealing\" another victim's payment and using it to unlock their computer.\nIn a situation like this, where no unique ID is given to identify the encrypted computer and the email is publicly accessible, it could be a case where the main goal is to wipe a server or act as a decoy for another attack.", - "meta": { - "payment-method": "Bitcoin", - "price": "2", - "ransomnotes": [ - "Security Notice\n\nHey. Your hard disk is encrypted using RSA 2048 asymmetric encryption. To decrypt files you need to obtain the private key.\nIt means We are the only ones in the world to recover files back to you. Not even god can help you. Its all math and cryptography .\nIf you want your files back, Please send an email to 15fd9ngtetwjtdc@yopmail.com.\nWe don't know who are you, All what we need is some money and we are doing it for good cause.\nDon't panic if we don't answer you during 24 hours. It means that we didn't received your letter and write us again.\nYou can use of that bitcoin exchangers for transfering bitcoin.\nhttps://localbitcoins.com\nhttps://www.kraken.com\nPlease use english language in your letters. If you don't speak english then use https://translate.google.com to translate your letter on english language.\n\nProcess:\n1) Pay some BTC to our wallet address.(negotations almost impossible unless you are a russian citizen)\n2) We will send you private key and instructions to decrypt your hard drive\n3) Boom! You got your files back." - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/ransomware-hits-hpe-ilo-remote-management-interfaces/", - "https://twitter.com/M_Shahpasandi/status/989157283799162880", - "https://id-ransomware.blogspot.com/2018/04/hpe-ilo-ransomware.html" - ] - }, - "uuid": "39cb0268-528b-11e8-ac30-0fa44afdc8de", - "value": "HPE iLO 4 Ransomware" - }, - { - "description": "When Sigrun is executed it will first check \"HKEY_CURRENT_USER\\Keyboard Layout\\Preload\" to see if it is set to the Russian layout. If the computer is using a Russian layout, it will not encrypt the computer and just delete itself. Otherwise Sigrun will scan a computer for files to encrypt and skip any that match certain extensions, filenames, or are located in particular folders. ", - "meta": { - "extensions": [ - ".sigrun" - ], - "payment-method": "Bitcoin Email", - "price": "2500 $", - "ransomnotes": [ - "SIGRUN 1.0 RANSOMWARE\n\nAll your important files are encrypted\n\nYour files has been encrypted by sigrun ransomware with unique decryption key.\n\nThere is only one way to get your files back: contact with us, pay, and get decryptor software. \n\nWe accept Bitcoin and Dash, you can find exchangers on https://www.bitcoin.com/buy-bitcoin and https://www.dash.org/exchanges/ and others.\n\nYou have unique idkey (in a yellow frame), write it in letter when contact with us.\n\nAlso you can decrypt 3 files for test, its guarantee what we can decrypt your files.\n\nIDKEY:\n>>> [id_key] <<<\nContact information:\n\nemail: sigrun_decryptor@protonmail.ch", - "~~~~~~SIGRUN 1.0 RANSOMWARE~~~~~~~~~\n\nAttention! \n\nAll your files documents, photos, databases and other important files are encrypted and have the extension: .sigrun\n\nThe only method of recovering files is to purchase a private key. It is on our server and only we can recover your files. \n\nBut don't worry! You still can restore it!\n\nIn order to restore it you need to contact with us via e-mail.\n\n-----------------------------------------------\n|Our e-mail is: sigrun_decryptor@protonmail.ch|\n-----------------------------------------------\n\nAs a proof we will decrypt 3 files for free!\n\nPlease, attach this to your message:\n[id_key]" - ], - "ransomnotes-filenames": [ - "RESTORE-SIGRUN.html", - "RESTORE-SIGRUN.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/sigrun-ransomware-author-decrypting-russian-victims-for-free/", - "http://id-ransomware.blogspot.com/2018/05/sigrun-ransomware.html" - ] - }, - "uuid": "5a53eec2-6993-11e8-a4d5-67480005dcbd", - "value": "Sigrun Ransomware" - }, - { - "description": "Mostly Hidden Tear with some codes from Eda2 & seems compiled w/ Italian VS. Maybe related to OpsVenezuela?", - "meta": { - "extensions": [ - ".crybrazil" - ], - "payment-method": "Website", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/8/crybrazil.jpg" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/1002953824590614528", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/", - "https://id-ransomware.blogspot.com/2018/06/crybrazil-ransomware.html" - ] - }, - "uuid": "30625df6-6e3e-11e8-b0cf-a7103cb03e05", - "value": "CryBrazil" - }, - { - "description": "new destrucrtive ransomware called Pedcont that claims to encrypt files because the victim has accessed illegal content on the deep web. The screen then goes blank and becomes unresponsive.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.0065 (50 $)", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/8/De00yEDVQAE_p9z[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/ ", - "http://id-ransomware.blogspot.com/2018/06/pedcont-ransomware.html" - ] - }, - "uuid": "b0e074fc-6e45-11e8-8366-dbfc88552a23", - "value": "Pedcont" - }, - { - "description": "new Scarab Ransomware variant called DiskDoctor that appends the .DiskDoctor extension and drops a ransom note named HOW TO RECOVER ENCRYPTED FILES.TXT", - "meta": { - "extensions": [ - ".DiskDoctor" - ], - "payment-method": "Bitcoin Email", - "ransomnotes-filenames": [ - "HOW TO RECOVER ENCRYPTED FILES.TXT" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/8/De2sj4GW0AAuQer[1].jpg" - ], - "refs": [ - "https://id-ransomware.blogspot.com/2018/06/scarab-diskdoctor-ransomware.html", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/" - ], - "synonyms": [ - "Scarab-DiskDoctor" - ] - }, - "uuid": "aa66e0c2-6fb5-11e8-851d-4722b7b3e9b9", - "value": "DiskDoctor" - }, - { - "description": "Jakub Kroustek discovered the RedEye Ransomware, which appends the .RedEye extension and wipes the contents of the files. RedEye can also rewrite the MBR with a screen that gives authors contact info and YouTube channel. Bart also wrote an article on this ransomware detailing how it works and what it does on a system.The ransomware author contacted BleepingComputer and told us that this ransomware was never intended for distribution and was created just for fun.", - "meta": { - "extensions": [ - ".RedEye" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/8/DfCO0T2WsAQvclJ[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/", - "https://twitter.com/JakubKroustek/status/1004463935905509376", - "https://bartblaze.blogspot.com/2018/06/redeye-ransomware-theres-more-than.html", - "https://id-ransomware.blogspot.com/2018/06/redeye-ransomware.html" - ] - }, - "uuid": "e675e8fa-7065-11e8-95e0-cfdc107099d8", - "value": "RedEye" - }, - { - "description": "Typical ransom software, Aurora virus plays the role of blackmailing PC operators. It encrypts files and the encryption cipher it uses is pretty strong. After encryption, the virus attaches .aurora at the end of the file names that makes it impossible to open the data. Thereafter, it dispatches the ransom note totaling 6 copies, without any change to the main objective i.e., victims must write an electronic mail addressed to anonimus.mr@yahoo.com while stay connected until the criminals reply telling the ransom amount.", - "meta": { - "extensions": [ - ".aurora", - ".animus", - ".Aurora", - ".desu", - ".ONI" - ], - "payment-method": "Bitcoin", - "price": "100 - 500", - "ransomnotes": [ - "==========================# aurora ransomware #==========================\n\nSORRY! Your files are encrypted.\nFile contents are encrypted with random key.\nWe STRONGLY RECOMMEND you NOT to use any \"decryption tools\".\nThese tools can damage your data, making recover IMPOSSIBLE.\nAlso we recommend you not to contact data recovery companies.\nThey will just contact us, buy the key and sell it to you at a higher price.\nIf you want to decrypt your files, you have to get RSA private key.\nIn order to get private key, write here:\nbig.fish@vfemail.net\nAnd send me your id, your id:\n[redacted]\nAnd pay 200$ on 1GSbmCoKzkHVkSUxqdSH5t8SxJQVnQCeYf wallet\nIf someone else offers you files restoring, ask him for test decryption.\n Only we can successfully decrypt your files; knowing this can protect you from fraud.\nYou will receive instructions of what to do next.\n==========================# aurora ransomware #==========================", - "%UserProfile%wall.i", - "==========================# zorro ransomware #==========================\nSORRY! Your files are encrypted.\nFile contents are encrypted with random key.\nRandom key is encrypted with RSA public key (2048 bit)\n.We STRONGLY RECOMMEND you NOT to use any \"decryption tools\".\nThese tools can damage your data, making recover IMPOSSIBLE.\nAlso we recommend you not to contact data recovery companies.\nThey will just contact us, buy the key and sell it to you at a higher price.\nIf you want to decrypt your files, you need to get the RSA-key from us.\n--\nTo obtain an RSA-key, follow these steps in order:\n1. pay this sum 500$ to this BTC-purse: 18sj1xr86c3YHK44Mj2AXAycEsT2QLUFac\n2. write on the e-mail ochennado@tutanota.com or anastacialove21@mail.com indicating in the letter this ID-[id] and BTC-purse, from which paid.\nIn the reply letter you will receive an RSA-key and instructions on what to do next.\nWe guarantee you the recovery of files, if you do it right.\n==========================# zorro ransomware #==========================" - ], - "ransomnotes-filenames": [ - "#RECOVERY-PC#.txt", - "!-GET_MY_FILES-!.txt", - "@_RESTORE-FILES_@.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/a/aurora/ransom-note.jpg", - "https://www.bleepstatic.com/images/news/ransomware/a/aurora/wallpaper.jpg" - ], - "refs": [ - "https://www.spamfighter.com/News-21588-Aurora-Ransomware-Circulating-the-Cyber-Space.htm", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-8th-2018-crybrazil-cryptconsole-and-magniber/", - "https://twitter.com/demonslay335/status/1004435398687379456", - "https://www.bleepingcomputer.com/news/security/aurora-zorro-ransomware-actively-being-distributed/", - "https://id-ransomware.blogspot.com/2018/05/aurora-ransomware.html" - ], - "synonyms": [ - "Zorro Ransomware" - ] - }, - "uuid": "3ee0664e-706d-11e8-800d-9f690298b437", - "value": "Aurora Ransomware" - }, - { - "meta": { - "extensions": [ - ".digiworldhack@tutanota.com" - ], - "payment-method": "Bitcoin", - "price": "500 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/8/pgpsnippet-variant.jpg", - "http://id-ransomware.blogspot.com/2018/05/pgpsnippet-ransomware.html" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1005138187621191681" - ] - }, - "uuid": "682ff7ac-7073-11e8-8c8b-bf1271b8800b", - "value": "PGPSnippet Ransomware" - }, - { - "meta": { - "extensions": [ - ".SF" - ], - "payment-method": "Bitcoin Email", - "refs": [ - "https://twitter.com/demonslay335/status/1005136022282428419", - "https://id-ransomware.blogspot.com/2018/04/spartacus-ransomware.html" - ] - }, - "uuid": "fe42c270-7077-11e8-af82-d7bf7e6ab8a9", - "value": "Spartacus Ransomware" - }, - { - "description": "S!Ri found a new ransomware called Donut that appends the .donut extension and uses the email donutmmm@tutanota.com.", - "meta": { - "extensions": [ - ".donut" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/june/15/DfQI_lnXUAAukGK[1].jpg" - ], - "refs": [ - "https://twitter.com/siri_urz/status/1005438610806583296", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-june-15th-2018-dbger-scarab-and-more/", - "http://id-ransomware.blogspot.com/2018/06/donut-ransomware.html" - ] - }, - "uuid": "e57e1f4a-72da-11e8-8c0d-af46e8f393d2", - "value": "Donut" - }, - { - "description": "Ransomware as a Service", - "meta": { - "payment-method": "Bitcoin", - "price": "10", - "refs": [ - "https://twitter.com/Damian1338B/status/1005411102660923392", - "https://www.bleepingcomputer.com/news/security/nemes1s-raas-is-padcrypt-ransomwares-affiliate-system/", - "https://id-ransomware.blogspot.com/2017/01/nemesis-ransomware.html" - ] - }, - "uuid": "3ac0f41e-72e0-11e8-85a8-f7ae254ab629", - "value": "NemeS1S Ransomware" - }, - { - "description": "MalwareHunterTeam discovered a new Paradise Ransomware variant that uses the extension _V.0.0.0.1{paradise@all-ransomware.info}.prt and drops a ransom note named PARADISE_README_paradise@all-ransomware.info.txt.", - "meta": { - "extensions": [ - "_V.0.0.0.1{paradise@all-ransomware.info}.prt" - ], - "payment-method": "Bitcoin Email", - "ransomnotes-filenames": [ - "PARADISE_README_paradise@all-ransomware.info.txt" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/1005420103415017472", - "https://twitter.com/malwrhunterteam/status/993499349199056897", - "http://id-ransomware.blogspot.com/2017/09/paradise-ransomware.html" - ] - }, - "uuid": "db06d2e0-72f9-11e8-9413-73999e1a9373", - "value": "Paradise Ransomware" - }, - { - "description": "uses the .reycarnasi1983@protonmail.com.gw3w amd a ransom note named ScrewYou.txt", - "meta": { - "extensions": [ - ".reycarnasi1983@protonmail.com.gw3w", - ".ssananunak1987@protonmail.com.b2fr" - ], - "payment-method": "Bitcoin", - "price": "0.1 - 0.3", - "ransomnotes": [ - "Your files were encrypted with AES-256.\n\nAsk how to restore your files by email reycarnasi1983@protonmail.com\n\nUse only gmail.com, yahoo.com, protonmail.com.\nMessages written from other mail services we can not get.\n\nWe always respond to messages. If there is no answer within 24 hours, then write us with another email service.\n\n[OR]\n\nIf within 24 hours you have not received a response, you need to follow the following instructions:\n\na) Download and install TOR browser: https://www.torproject.org/download/download-easy.html.en\nb) From the TOR browser, follow the link: torbox3uiot6wchz.onion\nc) Register your e-mail (Sign Up)\nd) Write us on e-mail: reycarnasi1983@torbox3uiot6wchz.onion\nATTENTION: e-mail (reycarnasi1983@torbox3uiot6wchz.onion) accepts emails, only with e-mail registered in the TOR browser at torbox3uiot6wchz.onion\n\n################################\n\nAny actions on your part over encrypted files can damage them. Be sure to make backups!\n\n################################\n\nIn the message write us this ID:\n[redacted base64]-----END KEY-----", - "Your files were encrypted with AES-256.\n\nAsk how to restore your files by email ssananunak1987@protonmail.com\n\nUse only gmail.com, yahoo.com, protonmail.com.\nMessages written from other mail services we can not get.\n\nWe always respond to messages. If there is no answer within 24 hours, then write us with another email service.\n\n[OR]\n\nIf within 24 hours you have not received a response, you need to follow the following instructions:\n\na) Download and install TOR browser: https://www.torproject.org/download/download-easy.html.en\nb) From the TOR browser, follow the link: torbox3uiot6wchz.onion\nc) Register your e-mail (Sign Up)\nd) Write us on e-mail: ssananunak1987@torbox3uiot6wchz.onion\nATTENTION: e-mail (ssananunak1987@torbox3uiot6wchz.onion) accepts emails, only with e-mail registered in the TOR browser at torbox3uiot6wchz.onion\n\n################################\n\nAny actions on your part over encrypted files can damage them. Be sure to make backups!\n\n################################\n\nIn the message write us this ID:\n[redacted base64]" - ], - "ransomnotes-filenames": [ - "ScrewYou.txt", - "Readme.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1006220895302705154", - "https://id-ransomware.blogspot.com/2018/03/b2dr-ransomware.html" - ] - }, - "uuid": "4a341cf4-72ff-11e8-8371-b74902a1dff3", - "value": "B2DR Ransomware" - }, - { - "description": "uses the extension .codyprince92@mail.com.ovgm and drops a ransom note named Readme.txt", - "meta": { - "extensions": [ - ".codyprince92@mail.com.ovgm" - ], - "payment-method": "Email Tor", - "ransomnotes": [ - "Hello. Your files have been encrypted.\n\nFor help, write to this e-mail: codyprince92@mail.com\nAttach to the letter 1-2 files (no more than 3 MB) and your personal key.\n\n\nIf within 24 hours you have not received a response, you need to follow the following instructions:\n\n\na) Download and install TOR browser: https://www.torproject.org/download/download-easy.html.en\nb) From the TOR browser, follow the link: torbox3uiot6wchz.onion\nc) Register your e-mail (Sign Up)\nd) Write us on e-mail: codyprince@torbox3uiot6wchz.onion\n\n\nATTENTION: e-mail (codyprince@torbox3uiot6wchz.onion) accepts emails, only with e-mail registered in the TOR browser at torbox3uiot6wchz.onion\n\n\n\nYour personal key:\n\n[redacted hex]" - ], - "ransomnotes-filenames": [ - "Readme.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1006237353474756610", - "http://id-ransomware.blogspot.com/2017/05/yyto-ransomware.html" - ] - }, - "uuid": "ef38d8b4-7392-11e8-ba1e-cfb37f0b9c73", - "value": "YYTO Ransomware" - }, - { - "meta": { - "extensions": [ - ".qnbqw" - ], - "payment-method": "Email", - "ransomnotes": [ - "Your files was encrypted using AES-256 algorithm. Write me to e-mail: qnbqwqe@protonmail.com to get your decryption key.\nYour USERKEY: [redacted 1024 bytes in base64]" - ], - "ransomnotes-filenames": [ - "Notice.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1007334654918250496" - ] - }, - "uuid": "53e6e068-739c-11e8-aae4-df58f7f27ee5", - "value": "Unnamed ramsomware 2" - }, - { - "meta": { - "extensions": [ - ".[everbe@airmail.cc].everbe", - ".embrace", - "pain", - ".[yoursalvations@protonmail.ch].neverdies@tutanota.com" - ], - "payment-method": "Bitcoin", - "price": "3003 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsoIB_0U0AAXgEz[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/decryptor-released-for-the-everbe-ransomware/", - "https://twitter.com/malwrhunterteam/status/1065675918000234497", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-23rd-2018-stop-dharma-and-more/", - "http://id-ransomware.blogspot.com/2018/03/everbe-ransomware.html" - ] - }, - "uuid": "9d09ac4a-73a0-11e8-b71c-63b86eedf9a2", - "value": "Everbe Ransomware" - }, - { - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://www.johannesbader.ch/2015/03/the-dga-of-dircrypt/" - ] - }, - "related": [ - { - "dest-uuid": "61b2dd12-2381-429d-bb64-e3210804a462", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "cdcc59a0-955e-412d-b481-8dff4bce6fdf", - "value": "DirCrypt" - }, - { - "description": "The authors of the Satan ransomware have rebranded their \"product\" and they now go by the name of DBGer ransomware, according to security researcher MalwareHunter, who spotted this new version earlier today. The change was not only in name but also in the ransomware's modus operandi. According to the researcher, whose discovery was later confirmed by an Intezer code similarity analysis, the new (Satan) DBGer ransomware now also incorporates Mimikatz, an open-source password-dumping utility. The purpose of DBGer incorporating Mimikatz is for lateral movement inside compromised networks. This fits a recently observed trend in Satan's modus operandi.", - "meta": { - "extensions": [ - "image.png -- > [dbger@protonmail.com]image.png.dbger" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "Some files have been encrypted\nPlease send ( 1 ) bitcoins to my wallet address\nIf you paid, send the machine code to my email\nI will give you the key\nIf there is no payment within three days,\nwe will no longer support decryption\nIf you exceed the payment time, your data will be open to the public download\nWe support decrypting the test file.\nSend three small than 3 MB files to the email address\n\nBTC Wallet : [redacted]\nEmail: dbger@protonmail.com\nYour HardwareID:" - ], - "ransomnotes-filenames": [ - "_How_to_decrypt_files.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/u/986406/Ransomware/DBGer/DBGer-ransom-note.png" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/dbger-ransomware-uses-eternalblue-and-mimikatz-to-spread-across-networks/", - "http://id-ransomware.blogspot.com/2018/06/dbger-ransomware.html" - ] - }, - "uuid": "541a479c-73a5-11e8-9d70-47736508231f", - "value": "DBGer Ransomware" - }, - { - "description": "Hidden Tear variant discovered in October 2016. After activation, provides victims with an unlimited amount of time to gather the requested ransom money and pay it. Related unlock keys and the response sent to and from a Gmail addres", - "meta": { - "payment-method": "Bitcoin", - "price": "250 $", - "refs": [ - "https://www.accenture.com/t20180803T064557Z__w__/us-en/_acnmedia/PDF-83/Accenture-Cyber-Threatscape-Report-2018.pdf", - "https://id-ransomware.blogspot.com/2017/11/rastakhiz-ransomware.html" - ] - }, - "uuid": "884eaa14-9ba8-11e8-a6ec-7f903f720e60", - "value": "RASTAKHIZ" - }, - { - "description": "DUMB variant discovered on November 16, 2017. Disguised itself as a popular virtual private network (VPN) in Iran known as Psiphon and infected Iranian users. Included Farsi-language ransom note, decryptable in the same way as previous DUMB-based variants. Message requested only US$15 for unlock key. Advertised two local and Iran-based payment processors: exchange.ir and webmoney.ir.Shared unique and specialized indicators with RASTAKHIZ; iDefense threat intelligence analysts believe this similarity confirms that the same actor was behind the repurposing of both types of ransomware.", - "meta": { - "payment-method": "Bitcoin", - "price": "15 $", - "refs": [ - "https://www.accenture.com/t20180803T064557Z__w__/us-en/_acnmedia/PDF-83/Accenture-Cyber-Threatscape-Report-2018.pdf", - "http://id-ransomware.blogspot.com/2017/10/tyrant-ransomware.html" - ], - "synonyms": [ - "Crypto Tyrant" - ] - }, - "uuid": "701f2a3e-9baa-11e8-a044-4b8bc49ea971", - "value": "TYRANT" - }, - { - "description": "zCrypt variant discovered on November 17, 2017, one day after the discovery of TYRANT. Used Farsi-language ransom note asking for a staggering 20 Bitcoin ransom payment. Also advertised local Iran-based payment processors and exchanges—www.exchangeing[.]ir, www.payment24[.]ir, www.farhadexchange.net, and www.digiarz.com)—through which Bitcoins could be acquired.", - "meta": { - "payment-method": "Bitcoin", - "price": "20", - "refs": [ - "https://www.accenture.com/t20180803T064557Z__w__/us-en/_acnmedia/PDF-83/Accenture-Cyber-Threatscape-Report-2018.pdf", - "https://id-ransomware.blogspot.com/2017/11/wannasmile-ransomware.html" - ] - }, - "uuid": "b3f04486-9bc4-11e8-bbfe-cf096483b45e", - "value": "WannaSmile" - }, - { - "description": "Uses APK Editor Pro. Picks and activates DEX>Smali from APK Editor. Utilizes LockService application and edits the “const-string v4, value” to a desired unlock key. Changes contact information within the ransom note. Once the victim has downloaded the malicious app, the only way to recover its content is to pay the ransom and receive the unlock key. ", - "meta": { - "payment-method": "Email", - "refs": [ - "https://www.accenture.com/t20180803T064557Z__w__/us-en/_acnmedia/PDF-83/Accenture-Cyber-Threatscape-Report-2018.pdf" - ] - }, - "uuid": "b48a7d62-9bc4-11e8-a7c5-47d13fad265f", - "value": "Unnamed Android Ransomware" - }, - { - "description": "A new distribution campaign is underway for a STOP Ransomware variant called KeyPass based on the amount of victims that have been seen. Unfortunately, how the ransomware is being distributed is unknown at this time.", - "meta": { - "extensions": [ - ".KEYPASS" - ], - "payment-method": "Bitcoin", - "price": "300 $", - "ransomnotes": [ - "Attention!\n\nAll your files, documents, photos, databases and other important files are encrypted and have the extension: .KEYPASS\n\nThe only method of recovering files is to purchase an decrypt software and unique private key.\n\nAfter purchase you will start decrypt software, enter your unique private key and it will decrypt all your data.\n\nOnly we can give you this key and only we can recover your files.\n\nYou need to contact us by e-mail keypass@bitmessage.ch send us your personal ID and wait for further instructions.\n\nFor you to be sure, that we can decrypt your files - you can send us a 1-3 any not very big encrypted files and we will send you back it in a original form FREE.\n\nPrice for decryption $300.\n\nThis price avaliable if you contact us first 72 hours.\n\nE-mail address to contact us:\n\nkeypass@bitmessage.ch\n\n\n\nReserve e-mail address to contact us:\n\nkeypass@india.com\n\n\n\nYour personal id:\n[id]" - ], - "ransomnotes-filenames": [ - "!!!KEYPASS_DECRYPTION_INFO!!!.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/new-keypass-ransomware-campaign-underway/", - "https://www.kaspersky.com/blog/keypass-ransomware/23447/" - ], - "synonyms": [ - "KeyPass" - ] - }, - "uuid": "22b4070e-9efe-11e8-b617-ab269f54596c", - "value": "KEYPASS" - }, - { - "description": "Emmanuel_ADC-Soft found a new STOP Ransomware variant that appends the .INFOWAIT extension and drops a ransom note named !readme.txt.", - "meta": { - "extensions": [ - ".INFOWAIT", - "-DATASTOP", - ".PUMA" - ], - "payment-method": "Bitcoin", - "price": "200 - 600 $", - "ransomnotes-filenames": [ - "!readme.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsW33OQXgAAwJzv[1].jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsobVENXcAAR3GC[1].jpg" - ], - "refs": [ - "https://twitter.com/Emm_ADC_Soft/status/1064459080016760833", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-23rd-2018-stop-dharma-and-more/", - "https://twitter.com/MarceloRivero/status/1065694365056679936", - "http://id-ransomware.blogspot.com/2017/12/stop-ransomware.html" - ] - }, - "uuid": "c76c4d24-9f99-11e8-808d-a7f1c66a53c5", - "value": "STOP Ransomware" - }, - { - "description": "A new ransomware that only encrypts .EXE files on a computer. It then displays a screen with a picture of President Obama that asks for a \"tip\" to decrypt the files.", - "meta": { - "payment-method": "Bitcoin", - "ransomnotes": [ - "Hello, your computer is encrypted by me! Yeah, that means your EXE file isn't open! Because I encrypted it.\nSo you can decrypt it, but you have to tip it. This is a big thing. You can email this email: 2200287831@qq.com gets more information." - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/b/barack-obama-ransomware/barack-obama-everlasting-blue-blackmail-virus.jpg" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/1032242391665790981", - "https://www.bleepingcomputer.com/news/security/barack-obamas-blackmail-virus-ransomware-only-encrypts-exe-files/", - "https://id-ransomware.blogspot.com/2018/08/barack-obamas-ransomware.html" - ], - "synonyms": [ - "Barack Obama's Blackmail Virus Ransomware" - ] - }, - "uuid": "1a98f5ca-b024-11e8-b828-1fb7dbd6619e", - "value": "Barack Obama's Everlasting Blue Blackmail Virus Ransomware" - }, - { - "description": "When the CryptoNar, or Crypto Nar, Ransomware encrypts a victims files it will perform the encryption differently depending on the type of file being encrypted.\nIf the targeted file has a .txt or .md extension, it will encrypt the entire file and append the .fully.cryptoNar extension to the encrypted file's name. All other files will only have the first 1,024 bytes encrypted and will have the .partially.cryptoNar extensions appended to the file's name.", - "meta": { - "extensions": [ - ".fully.cryptoNar", - ".partially.cryptoNar" - ], - "payment-method": "Bitcoin", - "price": "200 $", - "ransomnotes-filenames": [ - "CRYPTONAR RECOVERY INFORMATION.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/august/31/ransom-note.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/cryptonar-ransomware-discovered-and-quickly-decrypted/", - "https://twitter.com/malwrhunterteam/status/1034492151541977088", - "https://id-ransomware.blogspot.com/2018/08/cryptonar-ransomware.html" - ] - }, - "related": [ - { - "dest-uuid": "2fb307a2-8752-4521-8973-75b68703030d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "10f92054-b028-11e8-a51f-2f82236ac72d", - "value": "CryptoNar" - }, - { - "description": "Jakub Kroustek found what appears to be an in-dev version of the CreamPie Ransomware. It does not currently display a ransom note, but does encrypt files and appends the .[backdata@cock.li].CreamPie extension to them.", - "meta": { - "extensions": [ - ".[backdata@cock.li].CreamPie" - ], - "payment-method": "Bitcoin", - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/", - "https://twitter.com/JakubKroustek/status/1033656080839139333", - "https://id-ransomware.blogspot.com/2018/08/creampie-ransomware.html" - ] - }, - "uuid": "1b5a756e-b034-11e8-9e7d-c3271796acab", - "value": "CreamPie Ransomware" - }, - { - "description": "Looks to be in-development as it does not encrypt.", - "meta": { - "refs": [ - "https://twitter.com/leotpsc/status/1033625496003731458", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/" - ] - }, - "uuid": "7854c8bc-b036-11e8-bfb0-4ff71e54bbb2", - "value": "Jeff the Ransomware" - }, - { - "description": "Michael Gillespie saw an encrypted file uploaded to ID Ransomware that appends the .cassetto extension and drops a ransom note named IMPORTANT ABOUT DECRYPT.txt.", - "meta": { - "extensions": [ - ".cassetto" - ], - "payment-method": "Bitcoin", - "price": "0.5", - "ransomnotes": [ - "L!W2Be%BS4\nWARNING!! YOU ARE SO F*UCKED!!!\n\nYour Files Has Encrypted\n\nWhat happened to your files?\nAll of your files were protected by a strong encryptation\nThere is no way to decrypt your files without the key.\nIf your files not important for you just reinstall your system.\nx§If your files is important just email us to discuss the the price and how to decrypt your files.\n\nYou can email us to omg-help-me@openmailbox.org\n\nWe accept just BITCOIN if you don´t know what it is just google it.\nWe will give instructions where and how you buy bitcoin in your country.\nPrice depends on how important your files and network is.\nIt could be 0.5 bitcoin to 25 bitcoin.\nYou can send us a encrypted file for decryption.\nFell free to email us with your country, computer name and username of the infected system." - ], - "ransomnotes-filenames": [ - "IMPORTANT ABOUT DECRYPT.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/august/31/DlpDe-kXsAA2lmH[1].jpg" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1034213399922524160", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/", - "https://id-ransomware.blogspot.com/2018/08/cassetto-ransomware.html" - ] - }, - "uuid": "7d3287f0-b03d-11e8-b1ef-23485f43e7f9", - "value": "Cassetto Ransomware" - }, - { - "description": "Leo discovered a screenlocker that calls itself Acroware Cryptolocker Ransomware. It does not encrypt.", - "meta": { - "payment-method": "Bitcoin", - "price": "80 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/august/31/Dlq8W3FXoAAYR1v[1].jpg" - ], - "refs": [ - "https://twitter.com/leotpsc/status/1034346447112679430", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/" - ], - "synonyms": [ - "Acroware Screenlocker" - ] - }, - "uuid": "f1b76b66-b044-11e8-8ae7-cbe7e28dd584", - "value": "Acroware Cryptolocker Ransomware" - }, - { - "description": "Ben Hunter discovered a new ransomware called Termite Ransomware. When encrypting a computer it will append the .aaaaaa extension to encrypted files.", - "meta": { - "extensions": [ - ".aaaaaa" - ], - "payment-method": "Bitcoin", - "price": "100 - 500 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/august/31/DlraMbTWwAA_367[1].jpg" - ], - "refs": [ - "https://twitter.com/B_H101/status/1034379267956715520", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/" - ] - }, - "uuid": "a8a772b4-b04d-11e8-ad94-ab9124dff412", - "value": "Termite Ransomware" - }, - { - "description": "S!Ri found a new Thanatos Ransomware variant called PICO Ransomware. This ransomware will append the .PICO extension to encrypted files and drop a ransom note named README.txt.", - "meta": { - "extensions": [ - ".PICO" - ], - "payment-method": "Bitcoin", - "price": "100 $", - "ransomnotes-filenames": [ - "README.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/august/31/Dl2M9kdX0AAcGbJ[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-august-31st-2018-devs-on-vacation/", - "https://twitter.com/siri_urz/status/1035138577934557184" - ], - "synonyms": [ - "Pico Ransomware" - ] - }, - "uuid": "5d0c28f6-b050-11e8-95a8-7b8e480b9bd2", - "value": "PICO Ransomware" - }, - { - "description": "Today one of our volunteers, Aura, told me about a new new malspam campaign pretending to be from Craigslist that is under way and distributing the Sigma Ransomware. These spam emails contain password protected Word or RTF documents that download the Sigma Ransomware executable from a remote site and install it on a recipients computer.", - "meta": { - "payment-method": "Bitcoin", - "price": "400 $", - "ransomnotes-filenames": [ - "ReadMe.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/s/sigma/craigslist-malspam/ransom-note-html-part_01.jpg", - "https://www.bleepstatic.com/images/news/ransomware/s/sigma/craigslist-malspam/ransom-note-html-part_02.jpg", - "https://www.bleepstatic.com/images/news/ransomware/s/sigma/craigslist-malspam/payment-portal.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/sigma-ransomware-being-distributed-using-fake-craigslist-malspam/" - ] - }, - "uuid": "df025902-b29e-11e8-a2ab-739167419c52", - "value": "Sigma Ransomware" - }, - { - "uuid": "32406292-b738-11e8-ab97-1f674b130624", - "value": "Crypt0saur" - }, - { - "description": "An attack called Mongo Lock is targeting remotely accessible and unprotected MongoDB databases, wiping them, and then demanding a ransom in order to get the contents back. While this new campaign is using a name to identify itself, these types of attacks are not new and MongoDB databases have been targeted for a while now. These hijacks work by attackers scanning the Internet or using services such as Shodan.io to search for unprotected MongoDB servers. Once connected, the attackers may export the databases, delete them, and then create a ransom note explaining how to get the databases back.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes": [ - "Your database was encrypted by 'Mongo Lock'. if you want to decrypt your database, need to be pay us 0.1 BTC (Bitcoins), also don't delete 'Unique_KEY' and save it to safe place, without that we cannot help you. Send email to us: mongodb@8chan.co for decryption service." - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/mongo-lock-attack-ransoming-deleted-mongodb-databases/" - ] - }, - "uuid": "2aa481fe-c254-11e8-ad1c-efee78419960", - "value": "Mongo Lock" - }, - { - "description": "The Kraken Cryptor Ransomware is a newer ransomware that was released in August 2018. A new version, called Kraken Cryptor 1.5, was recently released that is masquerading as the legitimate SuperAntiSpyware anti-malware program in order to trick users into installing it. ", - "meta": { - "payment-method": "Dollars", - "price": "80", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/security/f/fallout-exploit-kit/savefiles/ransom-note-red.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/fallout-exploit-kit-now-installing-the-kraken-cryptor-ransomware/", - "https://www.bleepingcomputer.com/news/security/kraken-cryptor-ransomware-masquerading-as-superantispyware-security-program/", - "https://twitter.com/MarceloRivero/status/1059575186117328898", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-9th-2018-mostly-dharma-variants/" - ] - }, - "uuid": "c49f88f6-c87d-11e8-b005-d76e8162ced5", - "value": "Kraken Cryptor Ransomware" - }, - { - "meta": { - "extensions": [ - ".SAVEfiles." - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "!!!SAVE__FILES__INFO!!!.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/security/f/fallout-exploit-kit/savefiles/ransom-note-red.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/fallout-exploit-kit-pushing-the-savefiles-ransomware/" - ] - }, - "uuid": "76bfb132-cc70-11e8-8623-bb3f209be6c9", - "value": "SAVEfiles" - }, - { - "description": "The File-Locker Ransomware is a Hidden Tear variant that is targeting victims in Korea. When victim's are infected it will leave a ransom requesting 50,000 Won, or approximately 50 USD, to get the files back. This ransomware uses AES encryption with a static password of \"dnwls07193147\", so it is easily decryptable.", - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Won", - "price": "50 000 (50 $)", - "ransomnotes": [ - "한국어: 경고!!! 모든 문서, 사진, 데이테베이스 및 기타 중요한 파일이 암호화되었습니다!!\n당신은 돈을 지불해야 합니다\n비트코인 5만원을 fasfry2323@naver.com로 보내십시오 비트코인 지불코드: 1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX 결제 사이트 http://www.localbitcoins.com/ \nEnglish: Warning!!! All your documents, photos, databases and other important personal files were encrypted!!\nYou have to pay for it.\nSend fifty thousand won to fasfry2323@naver.com Bitcoin payment code: 1BoatSLRHtKNngkdXEeobR76b53LETtpyT Payment site http://www.localbitcoins.com/" - ], - "ransomnotes-filenames": [ - "Warning!!!!!!.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/f/file-locker/ransom-note%20-%20Copy.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/file-locker-ransomware-targets-korean-victims-and-asks-for-50k-won/" - ] - }, - "uuid": "c06a1938-dcee-11e8-bc74-474b0080f0e5", - "value": "File-Locker" - }, - { - "description": "A new ransomware called CommonRansom was discovered that has a very bizarre request. In order to decrypt a computer after a payment is made, they require the victim to open up Remote Desktop Services on the affected computer and send them admin credentials in order to decrypt the victim's files.", - "meta": { - "extensions": [ - ".[old@nuke.africa].CommonRansom" - ], - "payment-method": "Bitcoin", - "price": "0.1", - "ransomnotes": [ - "+-----------------------+\n¦----+CommonRansom+-----¦\n+-----------------------+\nHello dear friend,\nYour files were encrypted!\nYou have only 12 hours to decrypt it\nIn case of no answer our team will delete your decryption password\nWrite back to our e-mail: old@nuke.africa\n\n\nIn your message you have to write:\n1. This ID-[VICTIM_ID]\n2. [IP_ADDRESS]:PORT(rdp) of infected machine\n3. Username:Password with admin rights\n4. Time when you have paid 0.1 btc to this bitcoin wallet:\n35M1ZJhTaTi4iduUfZeNA75iByjoQ9ibgF\n\n\nAfter payment our team will decrypt your files immediatly\n\n\nFree decryption as guarantee:\n1. File must be less than 10MB\n2. Only .txt or .lnk files, no databases\n3. Only 5 files\n\n\nHow to obtain bitcoin:\nThe easiest way to buy bitcoins is LocalBitcoins site. You have to register, click 'Buy bitcoins', and select the seller by payment method and price.\nhttps://localbitcoins.com/buy_bitcoins\nAlso you can find other places to buy Bitcoins and beginners guide here:\nhttp://www.coindesk.com/information/how-can-i-buy-bitcoins/" - ], - "ransomnotes-filenames": [ - "DECRYPTING.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/c/CommonRansom/ransom-note.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/commonransom-ransomware-demands-rdp-access-to-decrypt-files/" - ] - }, - "uuid": "c0dffb94-dcee-11e8-81b9-3791d1c6638f", - "value": "CommonRansom" - }, - { - "description": "MalwareHunterTeam found a new ransomware called God Crypt that does not appear to decrypt and appears to be a joke ransomware. Has an unlock code of 29b579fb811f05c3c334a2bd2646a27a.", - "meta": { - "payment-method": "Bitcoin Website", - "refs": [ - "https://twitter.com/malwrhunterteam/status/1048616343975682048", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/" - ], - "synonyms": [ - "Godsomware v1.0", - "Ransomware God Crypt" - ] - }, - "uuid": "1b74bfda-c32c-4713-8ff6-793d8e787645", - "value": "God Crypt Joke Ransomware" - }, - { - "description": "Michael Gillespie found a new ransomware uploaded to ID Ransomware that appends the .encr extension and drops a ransom note named readmy.txt.", - "meta": { - "extensions": [ - ".encr" - ], - "payment-method": "Email", - "ransomnotes": [ - "Attention! All your files are encrypted!\nTo recover your files and access them,\nsend a message with your id to email DecryptFox@protonmail.com\n \nPlease note when installing or running antivirus will be deleted\n important file to decrypt your files and data will be lost forever!!!!\n \nYou have 5 attempts to enter the code. If you exceed this\nthe number, all the data, will be irreversibly corrupted. Be\ncareful when entering the code!\n \nyour id [redacted 32 lowercase hex]" - ], - "ransomnotes-filenames": [ - "readmy.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/", - "https://twitter.com/demonslay335/status/1049325784979132417" - ] - }, - "uuid": "a920dea5-9f30-4fa2-9665-63f306874381", - "value": "DecryptFox Ransomware" - }, - { - "description": "Michael Gillespie found a new ransomware that appends the .garrantydecrypt extension and drops a ransom note named #RECOVERY_FILES#.txt", - "meta": { - "extensions": [ - ".garrantydecrypt" - ], - "payment-method": "Bitcoin", - "price": "780 $", - "ransomnotes-filenames": [ - "#RECOVERY_FILES#.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-october-12th-2018-notpetya-gandcrab-and-more/", - "https://www.bleepingcomputer.com/news/security/ransomware-pretends-to-be-proton-security-team-securing-data-from-hackers/" - ] - }, - "uuid": "f251740b-1594-460a-a378-371f3a2ae92c", - "value": "garrantydecrypt" - }, - { - "description": "Siri discovered a new ransomware that is appending the .mvp extension to encrypted files.", - "meta": { - "extensions": [ - ".mvp" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/september/14/mvp.jpg" - ], - "refs": [ - "https://twitter.com/siri_urz/status/1039077365039673344", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-september-14th-2018-kraken-dharma-and-matrix/" - ] - }, - "uuid": "ea643bfd-613e-44d7-9408-4991d53e08fa", - "value": "MVP Ransomware" - }, - { - "description": "Michael Gillespie noticed numerous submissions to ID Ransomware from South Korea for the StorageCrypter ransomware. This version is using a new ransom note named read_me_for_recover_your_files.txt.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.8", - "ransomnotes": [ - "All your important files on this device have been encrypted.\n\nNo one can decrypt your files except us.\n\nIf you want to recover all your files. contact us via E-mail.\nDON'T forget to send us your ID!!!\n\nTo recover your files,You have to pay 0.8 bitcoin.\n\n\n\n\nContact Email : Leviathan13@protonmail.com\n\nYour ID :\n\n[redacted 0x200 bytes in base64 form]\n\n\nFree decryption as guarantee\n\nIf you can afford the specified amount of bitcoin,\nyou can send to us up to 2 files for demonstration.\n\nPlease note that files must NOT contain valuable information\nand their total size must be less than 2Mb." - ], - "ransomnotes-filenames": [ - "read_me_for_recover_your_files.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-september-14th-2018-kraken-dharma-and-matrix/" - ], - "synonyms": [ - "SambaCry" - ] - }, - "uuid": "3675e50d-3f76-45f8-b3f3-4a645779e14d", - "value": "StorageCrypter" - }, - { - "description": "GrujaRS discovered a new ransomware called Rektware that appends the .CQScSFy extension", - "meta": { - "extensions": [ - ".CQScSFy" - ], - "payment-method": "Email", - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-september-14th-2018-kraken-dharma-and-matrix/", - "https://twitter.com/GrujaRS/status/1040677247735279616" - ] - }, - "uuid": "e90a57b5-cd17-4dce-b83f-d007053c7b35", - "value": "Rektware" - }, - { - "meta": { - "extensions": [ - ".mariacbc" - ], - "payment-method": "Bitcoin", - "price": "0.002 (50 $)", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/9/moira.jpg" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/1058775145005887489", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-9th-2018-mostly-dharma-variants/" - ], - "synonyms": [ - "M@r1a", - "BlackHeart" - ] - }, - "uuid": "1009b7f3-e737-49fd-a872-1e0fd1df4c00", - "value": "M@r1a ransomware" - }, - { - "meta": { - "extensions": [ - "(enc) prepend" - ], - "payment-method": "Bitcoin", - "price": "25 000 sek (sweden)", - "ransomnotes": [ - "Hi. Thank you for using my program. If you're reading this, a lot of your files have\nbeen encrypted. To decrypt them, you need my decryption program. For this, I want 25 000 sek, I want\nthem in bitcoin. Email me when you've paid with details about the transaction. I'll give you two days.\nIf you have not paid in two days(from the day you received the email), It will cost 1000 sek more per day.\n If I have not heard from you after five days (from the day you received the email), I assume your files are not that\nimportant to you. So I'll delete your decryption-key, and you will never see your files again.\n\n\nAfter the payment, email me the following information:\n* the bitcoin address you sent from (important, write it down when you do the transaction)\n* the ID at the bottom of this document (this is important!! Otherwise I don't know which key belongs\nto you).\nThen I will send you the decryption-program and provide you with instructions of how to remove\nthe virus if you have not already figured it out.\n\n\nEmail:\naperfectday2018@protonmail.com\n\nBitcoin adress: \n1LX3tBkW161hoF5DbGzbrm3sdXaF6XHv2D\n\nMake sure to get the bitcoin adress right, copy and paste and double check. If you send the bitcoin\nto the wrong adress, it will be lost forever. You cant stop or regret a bitcoin transaction.\n\n\nIMPORTANT: \n\nDo not loose this document. You also have a copy of it on your desktop.\nDo NOT change any filenames!!! !!!\n\n\nThank you for the money, it means a lot to me. \n\n\n\nID: [redacted 13 numbers]" - ], - "ransomnotes-filenames": [ - "aboutYourFiles.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1059470985055875074", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-9th-2018-mostly-dharma-variants/" - ], - "synonyms": [ - "Aperfectday2018" - ] - }, - "uuid": "ad600737-6d5f-4771-ae80-3e434e29c749", - "value": "\"prepending (enc) ransomware\" (Not an official name)" - }, - { - "meta": { - "extensions": [ - ".impect" - ], - "payment-method": "Bitcoin", - "price": "300 $", - "ransomnotes": [ - "Attention MOTHERFUCKER!\n\nAll your main files were encrypted!\n\nYour personal files (documents, databases, jpeg, docx, doc,\netc.) were encrypted, their further using impossible.\nTO DECRYPT YOUR FILES YOU NEED TO BUY A SOFTWARE WITH YOUR UNIQUE PRIVATE KEY. ONLY OUR\nSOFTWARE WILL ALLOW YOU DECRYPT YOUR FILES.\nNOTE:\nYou have only 6 hours from the moment when an encryption was done to buy our software at $300, in bitcoin\nYou all files will get deleted after the lapse of 6 hours.\nAny attempts to remove this encryption will be unsuccessful. You cannot do this without our software with your key.\nDo not send any emails with threats and rudeness to us. Example of email format: Hi, I need a decryption of my files.\n\nBitcoin address = 1GstvLM6SumX3TMMgN9PvXQsEy3FR9ZqWX\n\nContact us by email only: ayaan321308@gmail.com" - ], - "ransomnotes-filenames": [ - "how to get back you files.txt" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/DrkmCriWwAMCdqF.jpg" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1060921043957755904" - ], - "synonyms": [ - "Dxh26wam" - ] - }, - "uuid": "f7fa6978-c932-4e62-b4fc-3fbbbc195602", - "value": "PyCL Ransomware" - }, - { - "description": "MalwareHunterTeam discovered the Vapor Ransomware that appends the .Vapor extension to encrypted files. Will delete files if you do not pay in time.", - "meta": { - "extensions": [ - ".Vapor" - ], - "payment-method": "Email", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/vapor.jpg" - ], - "refs": [ - "https://twitter.com/malwrhunterteam/status/1063769884608348160", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-23rd-2018-stop-dharma-and-more/" - ] - }, - "uuid": "f53205a0-7a8f-41d1-a427-bf3ab9bd77bb", - "value": "Vapor Ransomware" - }, - { - "description": "GrujaRS discovered a new ransomware called EnyBenyHorsuke Ransomware that appends the .Horsuke extension to encrypted files.", - "meta": { - "extensions": [ - ".Horsuke " - ], - "payment-method": "Bitcoin", - "price": "0.00000001", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsPVGaHXcAAtnXz[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-23rd-2018-stop-dharma-and-more/", - "https://twitter.com/GrujaRS/status/1063930127610986496" - ] - }, - "uuid": "677aeb47-587d-40a4-80b7-22672ba1160c", - "value": "EnyBenyHorsuke Ransomware" - }, - { - "meta": { - "extensions": [ - ".demonslay335_you_cannot_decrypt_me!", - ".malwarehunterteam" - ], - "payment-method": "Bitcoin", - "price": "999999.5", - "ransomnotes-filenames": [ - "!=How_recovery_files=!.html" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsiUA0LXgAAoqkd[1].jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/23/DsuMFrZW0AIIUXs[1].jpg" - ], - "refs": [ - "https://twitter.com/petrovic082/status/1065223932637315074", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-23rd-2018-stop-dharma-and-more/", - "https://twitter.com/demonslay335/status/1066099799705960448" - ], - "synonyms": [ - "DelphiMorix", - "DelphiMorix!" - ] - }, - "uuid": "7f82fb04-1bd2-40a1-9baa-895b53c6f7d4", - "value": "DeLpHiMoRix" - }, - { - "description": "@GrujaRS discovered a new in-dev ransomware called EnyBeny Nuclear Ransomware that meant to append the extension .PERSONAL_ID:.Nuclear to encrypted files, but failed due to a bug.", - "meta": { - "extensions": [ - ".PERSONAL_ID:.Nuclear" - ], - "payment-method": "Bitcoin", - "price": "0.00000001", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/november/30/Ds4IYbfWsAECNuJ[1].jpg", - "https://pbs.twimg.com/media/Ds4IKL3X4AIHKrj.jpg", - "https://pbs.twimg.com/media/Ds4IYbfWsAECNuJ.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-30th-2018-indictments-sanctions-and-more/", - "https://twitter.com/GrujaRS/status/1066799421080461312", - "https://www.youtube.com/watch?v=_aaFon7FVbc" - ] - }, - "uuid": "950d5501-b5eb-4f53-b33d-76e789912c16", - "value": "EnyBeny Nuclear Ransomware" - }, - { - "description": "Michael Gillespie discovered a new ransomware that renamed encrypted files to \"[[email]][original].[random].lucky\" and drops a ransom note named _How_To_Decrypt_My_File_.txt.", - "meta": { - "extensions": [ - "[]..lucky" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes": [ - "I am sorry to tell you.\nSome files has crypted\nif you want your files back , send 1 bitcoin to my wallet\nmy wallet address : 3HCBsZ6QQTnSsthbmVtYE4XSZtism4j7qd\nIf you have any questions, please contact us.\n\nEmail:[nmare@cock.li]" - ], - "ransomnotes-filenames": [ - "_How_To_Decrypt_My_File_.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1067109661076262913", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-november-30th-2018-indictments-sanctions-and-more/" - ] - }, - "uuid": "a8eb9743-dfb6-4e13-a95e-e68153df94e9", - "value": "Lucky Ransomware" - }, - { - "description": "Over 100,000 thousand computers in China have been infected in just a few days with poorly-written ransomware that encrypts local files and steals credentials for multiple Chinese online services. The crooks show a screen titled UNNAMED1989 and demand the victim a ransom of 110 yuan ($16) in exchange for decrypting the files, payable via Tencent's WeChat payment service by scanning a QR code.", - "meta": { - "payment-method": "Yuan", - "price": "110 (16 $)", - "refs": [ - "https://www.bleepingcomputer.com/news/security/ransomware-infects-100k-pcs-in-china-demands-wechat-payment/", - "https://www.bleepingcomputer.com/news/security/chinese-police-arrest-dev-behind-unnamed1989-wechat-ransomware/" - ], - "synonyms": [ - "UNNAMED1989" - ] - }, - "uuid": "b2aa807d-98fa-48e4-927b-4e81a50736e5", - "value": "WeChat Ransom" - }, - { - "meta": { - "extensions": [ - ".israbye" - ], - "payment-method": "Politic", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/december/7/Dtlxf0eW4AAJCdZ[1].jpg", - "https://pbs.twimg.com/media/DtlxfFsW4AAs-Co.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-7th-2018-wechat-ransomware-scammers-and-more/", - "https://www.youtube.com/watch?v=QevoUzbqNTQ", - "https://twitter.com/GrujaRS/status/1070011234521673728" - ] - }, - "uuid": "3ade75c8-6ef7-4c54-84d0-cab0161d3415", - "value": "IsraBye" - }, - { - "meta": { - "extensions": [ - "prepend (encrypted)" - ], - "payment-method": "Bitcoin Website", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/december/7/DtkQKCDWoAM13kD[1].jpg" - ], - "refs": [ - "https://twitter.com/struppigel/status/1069905624954269696", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-7th-2018-wechat-ransomware-scammers-and-more/" - ] - }, - "related": [ - { - "dest-uuid": "c71819a4-f6ce-4265-b0cd-24a98d84321c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "d3337bec-fd4e-11e8-a3ad-e799cc59c59c", - "value": "Dablio Ransomware" - }, - { - "meta": { - "extensions": [ - ".XY6LR", - ".gerber5", - ".FJ7QvaR9VUmi" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "DECRYPT.txt" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/Dtz4PD2WoAIWtRv.jpg", - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/december/14/Dt-APfCW0AADWV8[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-7th-2018-wechat-ransomware-scammers-and-more/", - "https://twitter.com/petrovic082/status/1071003939015925760", - "https://twitter.com/Emm_ADC_Soft/status/1071716275590782976" - ] - }, - "uuid": "3bcc725f-6b89-4350-ad79-f50daa30f74e", - "value": "Gerber Ransomware 1.0" - }, - { - "uuid": "54240144-05c2-43f0-8386-4301a85330bb", - "value": "Gerber Ransomware 3.0" - }, - { - "meta": { - "extensions": [ - ".protected" - ], - "payment-method": "Bitcoin", - "price": "900 $", - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2018/december/7/Dt1_DpMXcAMC8J_[1].jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-7th-2018-wechat-ransomware-scammers-and-more/", - "https://twitter.com/GrujaRS/status/1071153192975642630", - "https://www.youtube.com/watch?v=iB019lDvArs" - ] - }, - "uuid": "9ebfa028-a9dd-46ec-a915-1045fb297824", - "value": "Outsider" - }, - { - "description": "Uses http://ccrypt.sourceforge.net/ encryption program", - "meta": { - "payment-method": "Bitcoin", - "price": "0.3", - "refs": [ - "https://twitter.com/demonslay335/status/1071123090564923393", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-7th-2018-wechat-ransomware-scammers-and-more/" - ] - }, - "uuid": "23fcbbf1-93ee-4baf-9082-67ca26553643", - "value": "JungleSec" - }, - { - "description": "GrujaRS discovered the EQ Ransomware that drops a ransom note named README_BACK_FILES.htm and uses .f**k (censored) as its extension for encrypted files. May be GlobeImposter.", - "meta": { - "extensions": [ - ".fuck" - ], - "payment-method": "Bitcoin", - "price": "1", - "ransomnotes-filenames": [ - "README_BACK_FILES.htm" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/Dt4xTDjWwAEBjBh.jpg" - ], - "refs": [ - "https://twitter.com/GrujaRS/status/1071349228172124160", - "https://www.bleepingcomputer.com/news/security/the-week-in-ransomware-december-14th-2018-slow-week/", - "https://www.youtube.com/watch?v=uHYY6XZZEw4" - ] - }, - "uuid": "edd4c8d0-d971-40a6-b7c6-5c57a4b51e48", - "value": "EQ Ransomware" - }, - { - "description": "extension \".Mercury\", note \"!!!READ_IT!!!.txt\" with 4 different 64-char hex as ID, 3 of which have dashes. Possible filemarker, same in different victim's files.", - "meta": { - "extensions": [ - ".mercury" - ], - "payment-method": "Email", - "ransomnotes": [ - "!!! ATTENTION, YOUR FILES WERE ENCRYPTED !!!\n\nPlease follow few steps below:\n\n1.Send us your ID.\n2.We can decrypt 1 file what would you make sure that we have decription tool!\n3.Then you'll get payment instruction and after payment you will get your decryption tool!\n\n\n Do not try to rename files!!! Only we can decrypt all your data!\n\n Contact us:\n\ngetmydata@india.com\nmydataback@aol.com\n\n Your ID:[redacted 64 uppercase hex]:[redacted 64 uppercase hex with dashes]\n[redacted 64 uppercase hex with dashes]:[redacted 64 uppercase hex with dashes]" - ], - "ransomnotes-filenames": [ - "!!!READ_IT!!!.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1072164314608480257" - ] - }, - "uuid": "968cf828-0653-4d86-a01d-186db598f391", - "value": "Mercury Ransomware" - }, - { - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "ODSZYFRFUJ_PLIKI_TERAZ.txt" - ], - "ransomnotes-refs": [ - "https://pbs.twimg.com/media/DuIsIoWXQAEGKlr.jpg" - ], - "refs": [ - "https://twitter.com/GrujaRS/status/1072468548977680385" - ], - "synonyms": [ - "FORMA" - ] - }, - "uuid": "ea390fa7-94ac-4287-8a2d-c211330671b0", - "value": "Forma Ransomware" - }, - { - "meta": { - "extensions": [ - ".djvu" - ], - "payment-method": "Email", - "ransomnotes": [ - "---------------------------------------------- ALL YOUR FILES ARE ENCRYPTED ----------------------------------------------- \n\nDon't worry, you can return all your files!\nAll your files documents, photos, databases and other important are encrypted with strongest encryption and unique key.\nThe only method of recovering files is to purchase decrypt tool and unique key for you.\nThis software will decrypt all your encrypted files.\nWhat guarantees do we give to you?\nYou can send one of your encrypted file from your PC and we decrypt it for free.\nBut we can decrypt only 1 file for free. File must not contain valuable information\nDon't try to use third-party decrypt tools because it will destroy your files.\nDiscount 50% available if you contact us first 72 hours.\n\n---------------------------------------------------------------------------------------------------------------------------\n\n\nTo get this software you need write on our e-mail:\nhelpshadow@india.com\n\nReserve e-mail address to contact us:\nhelpshadow@firemail.cc\n\nYour personal ID:\n[redacted 43 alphanumeric chars]" - ], - "ransomnotes-filenames": [ - "_openme.txt" - ], - "refs": [ - "https://twitter.com/demonslay335/status/1072907748155842565" - ] - }, - "uuid": "e37ddc9e-8ceb-4817-a17e-755aa379ed14", - "value": "Djvu" - }, - { - "description": "Similar to Samas and BitPaymer, Ryuk is specifically used to target enterprise environments. Code comparison between versions of Ryuk and Hermes ransomware indicates that Ryuk was derived from the Hermes source code and has been under steady development since its release. Hermes is commodity ransomware that has been observed for sale on forums and used by multiple threat actors. However, Ryuk is only used by GRIM SPIDER and, unlike Hermes, Ryuk has only been used to target enterprise environments. Since Ryuk’s appearance in August, the threat actors operating it have netted over 705.80 BTC across 52 transactions for a total current value of $3,701,893.98 USD.", - "meta": { - "payment-method": "Bitcoin", - "price": "13.57", - "ransomnotes-filenames": [ - "RyukReadMe.txt" - ], - "ransomnotes-refs": [ - "https://www.crowdstrike.com/blog/wp-content/uploads/2019/01/RansomeNote-fig3.png", - "https://www.crowdstrike.com/blog/wp-content/uploads/2019/01/RansomeNote-fig4.png" - ], - "refs": [ - "https://www.crowdstrike.com/blog/big-game-hunting-with-ryuk-another-lucrative-targeted-ransomware/", - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2019-ACT-005.pdf" - ] - }, - "uuid": "f9464c80-b776-4f37-8682-ffde0cf8f718", - "value": "Ryuk ransomware" - }, - { - "description": "In August 2017, a new ransomware variant identified as BitPaymer was reported to have ransomed the U.K.’s National Health Service (NHS), with a high ransom demand of 53 BTC (approximately $200,000 USD). The targeting of an organization rather than individuals, and the high ransom demands, made BitPaymer stand out from other contemporary ransomware at the time. Though the encryption and ransom functionality of BitPaymer was not technically sophisticated, the malware contained multiple anti-analysis features that overlapped with Dridex. Later technical analysis of BitPaymer indicated that it had been developed by INDRIK SPIDER, suggesting the group had expanded its criminal operation to include ransomware as a monetization strategy.", - "meta": { - "payment-method": "Bitcoin Email", - "refs": [ - "https://www.crowdstrike.com/blog/big-game-hunting-the-evolution-of-indrik-spider-from-dridex-wire-fraud-to-bitpaymer-targeted-ransomware/" - ], - "synonyms": [ - "FriedEx", - "IEncrypt" - ] - }, - "uuid": "09fa0e0a-f0b2-46ea-8477-653e627b1c22", - "value": "BitPaymer" - }, - { - "meta": { - "extensions": [ - ".locked" - ], - "payment-method": "Email", - "ransomnotes-filenames": [ - "README-NOW.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/u/1100723/Ransomware/LockerGoga-ransom-note.png" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/new-lockergoga-ransomware-allegedly-used-in-altran-attack/", - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2019-ACT-005.pdf" - ] - }, - "related": [ - { - "dest-uuid": "0529c53a-afe7-4549-899e-3f8735467f96", - "tags": [ - "estimative-language:likelihood-probability=\"roughly-even-chance\"" - ], - "type": "similar" - } - ], - "uuid": "1e19dae5-80c3-4358-abcd-2bf0ba4c76fe", - "value": "LockerGoga" - }, - { - "description": "We have been observing a malvertising campaign via Rig exploit kit delivering a cryptocurrency-mining malware and the GandCrab ransomware since July 25. On August 1, we found Rig’s traffic stream dropping a then-unknown ransomware. Delving into this seemingly new ransomware, we checked its ransom payment page in the Tor network and saw it was called Princess Evolution (detected by Trend Micro as RANSOM_PRINCESSLOCKER.B), and was actually a new version of the Princess Locker ransomware that emerged in 2016. Based on its recent advertisement in underground forums, it appears that its operators are peddling Princess Evolution as a ransomware as a service (RaaS) and are looking for affiliates.\nThe new malvertising campaign we observed since July 25 is notable in that the malvertisements included Coinhive (COINMINER_MALXMR.TIDBF). Even if users aren’t diverted to the exploit kit and infected with the ransomware, the cybercriminals can still earn illicit profit through cryptocurrency mining. Another characteristic of this new campaign is that they hosted their malvertisement page on a free web hosting service and used domain name system canonical name (DNS CNAME) to map their advertisement domain on a malicious webpage on the service.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.12 (773 $)", - "refs": [ - "https://blog.trendmicro.com/trendlabs-security-intelligence/ransomware-as-a-service-princess-evolution-looking-for-affiliates/" - ], - "synonyms": [ - "PrincessLocker Evolution" - ] - }, - "uuid": "53da7991-62b7-4fe2-af02-447a0734f41d", - "value": "Princess Evolution" - }, - { - "description": "A new Ransomware-as-a-Service called Jokeroo is being promoted on underground hacking sites and via Twitter that allows affiliates to allegedly gain access to a fully functional ransomware and payment server.\nAccording to a malware researcher named Damian, the Jokeroo RaaS first started promoting itself as a GandCrab Ransomware RaaS on the underground hacking forum Exploit.in. ", - "meta": { - "payment-method": "Bitcoin", - "price": "0.0077", - "refs": [ - "https://www.bleepingcomputer.com/news/security/jokeroo-ransomware-as-a-service-offers-multiple-membership-packages/" - ], - "synonyms": [ - "Fake GandCrab" - ] - }, - "uuid": "8cfa694b-3e6b-410a-828f-037d981870b2", - "value": "Jokeroo" - }, - { - "description": "During December 2017, a new variant of the GlobeImposter Ransomware was detected for the first time and reported on malware-traffic-analysis. At first sight this ransomware looks very similar to other ransomware samples and uses common techniques such as process hollowing. However, deeper inspection showed that like LockPoS, which was analyzed by CyberBit, GlobeImposter too bypasses user-mode hooks by directly invoking system calls. Given this evasion technique is being leveraged by new malware samples may indicate that this is a beginning of a trend aiming to bypass user-mode security products.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.35", - "refs": [ - "https://www.fortinet.com/blog/threat-research/analysis-of-new-globeimposter-ransomware-variant.html" - ] - }, - "uuid": "a4631cef-dc51-4bee-a51f-3f1ea75ff201", - "value": "GlobeImposter" - }, - { - "description": "BlackWorm Ransomware is a malicious computer infection that encrypts your files, and then does everything it can to prevent you from restoring them. It needs you to pay $200 for the decryption key, but there is no guarantee that the people behind this infection would really issue the decryption tool for you.", - "meta": { - "payment-method": "Bitcoin", - "price": "200 $", - "refs": [ - "https://spyware-techie.com/blackworm-ransomware-removal-guide" - ] - }, - "uuid": "457e9a45-607e-41ef-8ad1-bf8684722445", - "value": "BlackWorm" - }, - { - "description": "Tellyouthepass is a ransomware that alters system files, registry entries and encodes personal photos, documents, and servers or archives. Army-grade encryption algorithms get used to change the original code of the file and make the data useless.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.2", - "refs": [ - "https://malware.wikia.org/wiki/Tellyouthepass" - ] - }, - "uuid": "c6ca9b44-d0cd-40c9-9d00-39e0f7bcae79", - "value": "Tellyouthepass" - }, - { - "description": "BigBobRoss ransomware is the cryptovirus that requires a ransom in Bitcoin to return encrypted files marked with .obfuscated appendix.", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://www.2-spyware.com/remove-bigbobross-ransomware.html" - ] - }, - "uuid": "5d3fc33b-8e90-4d9d-8f45-f047264ce8cb", - "value": "BigBobRoss" - }, - { - "description": "First discovered by malware security analyst, Lawrence Abrams, PLANETARY is an updated variant of another high-risk ransomware called HC7.", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://www.pcrisk.com/removal-guides/12121-planetary-ransomware" - ] - }, - "uuid": "7c742031-6b3d-4c3a-8b36-9154a6dc7b30", - "value": "Planetary" - }, - { - "description": "Cr1ptT0r Ransomware Targets NAS Devices with Old Firmware.", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://www.coveware.com/blog/2019/3/13/cr1ptt0r-ransomware-targets-nas-devices-with-old-firmware", - "https://malpedia.caad.fkie.fraunhofer.de/details/elf.cr1ptt0r" - ], - "synonyms": [ - "Criptt0r", - "Cr1pt0r", - "Cripttor" - ] - }, - "uuid": "e19d92d7-cf17-4b2b-8ec2-1efc6df2fa1e", - "value": "Cr1ptT0r" - }, - { - "description": "Attackers are actively exploiting a recently disclosed vulnerability in Oracle WebLogic to install a new variant of ransomware called \"Sodinokibi.\" Sodinokibi attempts to encrypt data in a user's directory and delete shadow copy backups to make data recovery more difficult. Oracle first patched the issue on April 26, outside of their normal patch cycle, and assigned it CVE-2019-2725. This vulnerability is easy for attackers to exploit, as anyone with HTTP access to the WebLogic server could carry out an attack. Because of this, the bug has a CVSS score of 9.8/10. Attackers have been making use of this exploit in the wild since at least April 17. Cisco's Incident Response (IR) team, along with Cisco Talos, are actively investigating these attacks and Sodinokibi.", - "meta": { - "refs": [ - "https://blog.talosintelligence.com/2019/04/sodinokibi-ransomware-exploits-weblogic.html" - ], - "synonyms": [ - "REvil", - "Revil" - ] - }, - "uuid": "24bd9a4b-2b66-428b-8e1c-6b280b056c00", - "value": "Sodinokibi" - }, - { - "description": "Phobos exploits open or poorly secured RDP ports to sneak inside networks and execute a ransomware attack, encrypting files and demanding a ransom be paid in bitcoin for returning the files, which in this case are locked with a .phobos extension.", - "meta": { - "payment-method": "Bitcoin", - "refs": [ - "https://www.zdnet.com/article/new-phobos-ransomware-exploits-weak-security-to-hit-targets-around-the-world/" - ], - "synonyms": [ - "Java NotDharma" - ] - }, - "uuid": "d2c7fb08-293e-453b-a213-adeb79505767", - "value": "Phobos" - }, - { - "description": "A new ransomware is in the dark market which encrypts all the files on the device and redirects victims to the RIG exploit kit.", - "meta": { - "payment-method": "Bitcoin", - "price": "300 $", - "refs": [ - "https://www.ehackingnews.com/2019/05/getcrypt-ransomware-modus-operandi-and.html" - ] - }, - "uuid": "7c9df1bd-9212-4ce3-b407-636e41bc4eea", - "value": "GetCrypt" - }, - { - "description": "A new ransomware family dubbed “Nemty” for the extension it adds to encrypted files has recently surfaced in the wild. According to a report from Bleeping Computer, New York-based reverse engineer Vitali Kremez posits that Nemty is possibly delivered through exposed remote desktop connections.", - "meta": { - "payment-method": "Bitcoin", - "price": "1000 $", - "refs": [ - "https://www.trendmicro.com/vinfo/us/security/news/cyber-attacks/nemty-ransomware-possibly-spreads-through-exposed-remote-desktop-connections" - ] - }, - "uuid": "5fb75933-1ed5-4512-a062-d39865eedab0", - "value": "Nemty" - }, - { - "description": "Buran is a new version of the Vega ransomware strain (a.k.a. Jamper, Ghost, Buhtrap) that attacked accountants from February through April 2019. The new Buran ransomware first was discovered by nao_sec in June 2019, delivered by the RIG Exploit Kit, as reported by BleepingComputer.", - "meta": { - "refs": [ - "https://www.acronis.com/en-us/blog/posts/meet-buran-new-delphi-ransomware-delivered-rig-exploit-kit" - ] - }, - "uuid": "a92b2165-29e7-463a-b3d5-c8b7d8a25f65", - "value": "Buran" - }, - { - "description": "The Hildacrypt ransomware encrypts the victim’s files with a strong encryption algorithm and the filename extension .hilda until the victim pays a fee to get them back.", - "meta": { - "refs": [ - "https://securitynews.sonicwall.com/xmlpost/hildacrypt-ransomware-actively-spreading-in-the-wild/" - ] - }, - "uuid": "25fcb177-7219-4414-b5de-8aeb2e6d146f", - "value": "Hildacrypt" - }, - { - "description": "Mr. Dec ransomware is cryptovirus that was first spotted in mid-May 2018, and since then was updated multiple times. The ransomware encrypts all personal data on the device with the help of AES encryption algorithm and appends .[ID]random 16 characters[ID] file extension, preventing from their further usage.", - "meta": { - "encryption": "AES", - "refs": [ - "https://www.2-spyware.com/remove-mr-dec-ransomware.html", - "https://id-ransomware.blogspot.com/2018/05/mrdec-ransomware.html" - ], - "synonyms": [ - "MrDec", - "Sherminator" - ] - }, - "uuid": "2e8aa6da-00b1-4222-b212-c48a7348893c", - "value": "Mr.Dec" - }, - { - "description": "Freezing crypto ransomware encrypts user data using AES, and then requires a ransom in # BTC to return the files. Original title: not indicated in the note. The file says: FreeMe.exe", - "meta": { - "encryption": "AES", - "refs": [ - "http://id-ransomware.blogspot.com/2019/06/freeme-freezing-ransomware.html" - ], - "synonyms": [ - "Freezing" - ] - }, - "uuid": "9b074569-b90c-44e6-b9b2-e6e19a48118d", - "value": "Freeme" - }, - { - "description": "We have dubbed this new ransomware DoppelPaymer because it shares most of its code with the BitPaymer ransomware operated by INDRIK SPIDER. However, there are a number of differences between DoppelPaymer and BitPaymer, which may signify that one or more members of INDRIK SPIDER have split from the group and forked the source code of both Dridex and BitPaymer to start their own Big Game Hunting ransomware operation.", - "meta": { - "encryption": "AES", - "refs": [ - "https://www.crowdstrike.com/blog/doppelpaymer-ransomware-and-dridex-2/", - "https://malpedia.caad.fkie.fraunhofer.de/details/win.doppelpaymer" - ] - }, - "uuid": "3d8989dc-9a10-4cae-ab24-ff0abed487f4", - "value": "DoppelPaymer" - }, - { - "description": "This crypto ransomware encrypts enterprise LAN data with AES (ECB mode), and then requires a ransom in # BTC to return the files.", - "meta": { - "encryption": "AES", - "refs": [ - "https://id-ransomware.blogspot.com/2019/01/unnamed-desync-ransomware.html" - ] - }, - "uuid": "e5288fc1-ff2a-4992-a1fb-6a8ef612de51", - "value": "Desync" - }, - { - "description": "Maze Ransomware encrypts files and makes them inaccessible while adding a custom extension containing part of the ID of the victim. The ransom note is placed inside a text file and an htm file. There are a few different extensions appended to files which are randomly generated.", - "meta": { - "encryption": "ChaCha20 and RSA", - "refs": [ - "https://malpedia.caad.fkie.fraunhofer.de/details/win.maze", - "https://www.bleepingcomputer.com/news/security/maze-ransomware-now-delivered-by-spelevo-exploit-kit/", - "https://www.proofpoint.com/us/threat-insight/post/ta2101-plays-government-imposter-distribute-malware-german-italian-and-us" - ] - }, - "related": [ - { - "dest-uuid": "e69f9836-873a-43d3-92a8-97ab783a4171", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "related-to" - } - ], - "uuid": "c60776a6-91dd-499b-8b4c-7940479e71fc", - "value": "Maze" - }, - { - "description": "Ransomware delivered using fake Windows Update spam", - "meta": { - "extensions": [ - ".777" - ], - "ransomnotes-filenames": [ - "Cyborg_DECRYPT.txt" - ], - "ransomnotes-refs": [ - "https://npercoco.typepad.com/.a/6a0133f264aa62970b0240a4ebff1b200b-pi" - ], - "refs": [ - "https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/fake-windows-update-spam-leads-to-cyborg-ransomware-and-its-builder/" - ] - }, - "uuid": "0a0b9311-8cbc-4d97-b337-42c9a018ebe0", - "value": "Cyborg Ransomware" - }, - { - "description": "A targeted email campaign has been spotted distributing the JasperLoader to victims. While the JasperLoader was originally used to then install Gootkit, Certego has observed it now being used to infect victims with a new ransomware dubbed FTCODE. Using an invoice-themed email appearing to target Italian users, the attackers attempt to convince users to allow macros in a Word document. The macro is used to run PowerShell to retrieve additional PowerShell code.", - "meta": { - "payment-method": "Bitcoin", - "price": "0.06", - "refs": [ - "https://www.certego.net/en/news/malware-tales-ftcode/", - "https://exchange.xforce.ibmcloud.com/collection/FTCODE-Ransomware-45dacdc2d5cf30722ced20b9d37988c2", - "https://malpedia.caad.fkie.fraunhofer.de/details/ps1.ftcode" - ] - }, - "uuid": "6f9b7c54-45fa-422c-97f0-0f0c015e3c4e", - "value": "FTCode" - }, - { - "description": "Observed for the first time in Febuary 2019, variant from CryptoMix Family, itself a variation from CryptXXX and CryptoWall family", - "meta": { - "extensions": [ - ".CIop", - ".Clop", - ".Ciop", - ".Clop2" - ], - "refs": [ - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2020-CTI-001.pdf" - ] - }, - "uuid": "21b349c3-ede2-4e11-abda-1444eb272eff", - "value": "Clop" - }, - { - "description": "A new infection is being distributed by porn sites that tries to blackmail a victim into paying a ransom by stating they will tell law enforcement that the victim is spreading child porn. This is done by collecting information about the user, including screen shots of their active desktop, in order to catch them in compromising situations.", - "meta": { - "ransomnotes": [ - "https://www.bleepstatic.com/images/news/malware/b/blackmailware/pornblackmailer/ransom-note.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/blackmailware-found-on-porn-site-threatens-to-report-users-are-spreading-child-porn/" - ] - }, - "uuid": "a1a730e2-f1a4-4d7b-9930-80529cd97f3c", - "value": "PornBlackmailer" - }, - { - "description": "This crypto-extortioner encrypts user data using AES, and then requires a $ 30- $ 50- $ 80 buy- back to BTC to return the files. The name is original. Written on AutoIt.", - "meta": { - "ransomnotes": [ - "Your files has been safely encrypted\n---\nEncrypted files: 276\n**********\n---\n[Buy Bitcoins] [Decrypt Files] (Decryptionkey)\n---\nThe only way you can recover your files is to buy a decryption key\nThe payment method is: Bitcoin. The price is: $50 = Bitcoins\nAfter buying the amount of bitcoins send an email\nto king.ouroboros@protonmail.com Your ID: *****\nWe will provide you with payment address and your decryption key.\nYou have 72 Hours to complete the payment otherwise your key will be deleted." - ], - "refs": [ - "https://id-ransomware.blogspot.com/2018/06/kingouroboros-ransomware.html" - ] - }, - "uuid": "303a07bf-c990-4fbe-ac7d-57b8c3cb29b6", - "value": "KingOuroboros" - }, - { - "description": "The ransomware appears to target users in Korea, and may have been developed with at least knowledge of the Korean language.", - "meta": { - "refs": [ - "https://bartblaze.blogspot.com/2018/08/mafia-ransomware-targeting-users-in.html" - ], - "synonyms": [ - "Mafia" - ] - }, - "uuid": "9ea6333f-1437-4a57-8acc-d73019378ef2", - "value": "MAFIA Ransomware" - }, - { - "description": "The cybercrime group that brought us Satan, DBGer and Lucky ransomware and perhaps Iron ransomware, has now come up with a new version or rebranding named 5ss5c. [...] It will however only encrypt files with the following extensions: 7z, bak, cer, csv, db, dbf, dmp, docx, eps, ldf, mdb, mdf, myd, myi, ora, pdf, pem, pfx, ppt, pptx, psd, rar, rtf, sql, tar, txt, vdi, vmdk, vmx, xls, xlsx, zip", - "meta": { - "ransomnotes-filenames": [ - "_如何解密我的文件_.txt" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-T0B4txHlNHs/Xh4-raVFVtI/AAAAAAAACTE/R-YoW8QHFLsuD140AF9vD-_rOifULExUgCLcBGAsYHQ/s1600/note.PNG" - ], - "refs": [ - "https://bartblaze.blogspot.com/2020/01/satan-ransomware-rebrands-as-5ss5c.html" - ] - }, - "uuid": "8ac9fc73-05db-4be8-8f46-33bbd6b3502b", - "value": "5ss5c Ransomware" - }, - { - "description": "Nodera is a ransomware family that uses the Node.js framework and was discovered by Quick Heal researchers. The infection chain starts with a VBS script embedded with multiple JavaScript files. Upon execution, a directory is created and both the main node.exe program and several required NodeJS files are downloaded into the directory. Additionally, a malicious JavaScript payload that performs the encryption process is saved in this directory. After checking that it has admin privileges and setting applicable variables, the malicious JavaScript file enumerates the drives to create a list of targets. Processes associated with common user file types are stopped and volume shadow copies are deleted. Finally, all user-specific files on the C: drive and all files on other drives are encrypted and are appended with a .encrypted extension. The ransom note containing instructions on paying the Bitcoin ransom are provided along with a batch script to be used for decryption after obtaining the private key. Some mistakes in the ransom note identified by the researchers include the fact that it mentions a 2048-bit RSA public key instead of 4096-bit (the size that was actually used), a hard-coded private key destruction time dating back almost 2 years ago, and a lack of instructions for how the private key will be obtained after the ransom is paid. These are signs that the ransomware may be in the development phase and was likely written by an amateur. For more information, see the QuickHeal blog post in the Reference section below.", - "meta": { - "extensions": [ - ".encrypted" - ], - "refs": [ - "https://exchange.xforce.ibmcloud.com/collection/6f18908ce6d9cf4efb551911e00d9ec4", - "https://blogs.quickheal.com/first-node-js-based-ransomware-nodera/" - ], - "synonyms": [ - "Nodera" - ] - }, - "uuid": "0529c53a-afe7-4549-899e-3f8735467f96", - "value": "Nodera Ransomware" - }, - { - "description": "Discovered in May 2019. dropped throught networks compromised by trojan like Emotet or TrickBot. Tools and methods used are similar to LockerGoga", - "meta": { - "refs": [ - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2020-CTI-001.pdf" - ] - }, - "related": [ - { - "dest-uuid": "1e19dae5-80c3-4358-abcd-2bf0ba4c76fe", - "tags": [ - "estimative-language:likelihood-probability=\"roughly-even-chance\"" - ], - "type": "similar" - } - ], - "uuid": "f1041289-f42b-416f-b649-7bb8e543011f", - "value": "MegaCortex" - }, - { - "description": "Detected in April 2019. Known for paralyzing the cities of Baltimore and Greenville. Probably also exfiltrate data", - "meta": { - "refs": [ - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2020-CTI-001.pdf" - ], - "synonyms": [ - "HelpYemen" - ] - }, - "uuid": "000fb0bf-8be3-4ff1-8bbd-cc0513bcdd89", - "value": "RobinHood" - }, - { - "description": "Bart ransomware is distributed by the same Russian Cyber Mafia behind Dridex 220 and Locky. Bart doesn't communicate with a command and control (C&C) server, so it can encrypt files without being connected to a computer.\nBart is spread to end users via phishing emails containing .zip attachments with JavaScript Code and use social engineering to trick users into opening the 'photo' attachments. The zipped files are obfuscated to make it more hard to tell what actions they are performing. See screenshot above for an example of what they look like. If opened, these attachments download and install the intermediary loader RockLoader which downloads Bart onto the machine over HTTPS.\nOnce executed, it will first check the language on the infected computer. If the malware detects Russian, Belorussian, or Ukrainian, the ransomware will terminate and will not proceed with the infection. If it's any other language, it will start scanning the computer for certain file extensions to encrypt.\nBecause Bart does not require communication with C&C infrastructure prior to encrypting files, Bart could possibly encrypt machines sitting behind corporate firewalls that would otherwise block such traffic. Thus, organizations need to ensure that Bart is blocked at the email gateway using rules that block zipped executables.", - "meta": { - "refs": [ - "https://www.knowbe4.com/bart-ransomware" - ], - "synonyms": [ - "Locky Bart" - ] - }, - "uuid": "05d5263f-ec23-4279-bb98-55fc233d7e89", - "value": "Bart ransomware" - }, - { - "description": "Razor was discovered by dnwls0719, it is a part of Garrantydecrypt ransomware family. Like many other programs of this type, Razor is designed to encrypt files (make them unusable/inaccessible), change their filenames, create a ransom note and change victim's desktop wallpaper. Razor renames files by appending the \".razor\" extension to their filenames. For example, it renames \"1.jpg\" to \"1.jpg.razor\", and so on. It creates a ransom note which is a text file named \"#RECOVERY#.txt\", this file contains instructions on how to contact Razor's developers (cyber criminals) and other details.\nAs stated in the \"#RECOVERY#.txt\" file, this ransomware encrypts all files and information about how to purchase a decryption tool can be received by contacting Razor's developers. Victims supposed to contact them via razor2020@protonmail.ch, Jabber client (razor2020@jxmpp.jp) or ICQ client (@razor2020) and wait for further instructions. It is very likely that they will name a price of a decryption tool and/or key and provide cryptocurrency wallet's address that should be used to make a transaction. However, it is never a good idea to trust (pay) any cyber criminals/ransomware developers. It is common that they do not provide decryption tools even after a payment. Another problem is that ransomware-type programs encrypt files with strong encryption algorithms and their developers are the only ones who have tools that can decrypt files encrypted by their ransomware. In most cases victims have the only free and safe option: to restore files from a backup. Also, it is worth mentioning that files remain encrypted even after uninstallation of ransomware, its removal only prevents it from causing further encryptions.", - "meta": { - "extensions": [ - ".razor" - ], - "ransomnotes": [ - "All your files have been ENCRYPTED!!!\nWrite to our email: \n razor2020@protonmail.ch\n ICQ:\n @razor2020\n Or contact us via jabber:\n razor2020@jxmpp.jp\nJabber (Pidgin) client installation instructions, you can find on youtube - hxxps://www.youtube.com/results?search_query=pidgin+jabber+install\nAttention!\nDo not rename encrypted files.\nDo not try to decrypt your data using third party software, it may cause permanent data loss.\ntell your unique ID" - ], - "ransomnotes-filenames": [ - "#RECOVERY#.txt" - ], - "ransomnotes-refs": [ - "https://www.pcrisk.com/images/stories/screenshots202002/razor-ransom-note.jpg" - ], - "refs": [ - "https://www.pcrisk.com/removal-guides/17016-razor-ransomware" - ] - }, - "uuid": "ea35282c-0686-4115-a001-bc4203549418", - "value": "Razor" - }, - { - "meta": { - "refs": [ - "https://www.microsoft.com/security/blog/2020/03/05/human-operated-ransomware-attacks-a-preventable-disaster/", - "https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=ransom:win32/wadhrama.c&ThreatID=2147730655" - ] - }, - "related": [ - { - "dest-uuid": "00edb40d-2fed-4d36-98b1-c85fc2bb1168", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "used-by" - } - ], - "uuid": "42148074-196b-4f8c-b149-12163fc385fa", - "value": "Wadhrama" - }, - { - "description": "Mespinoza ransomware is used at least since october 2018. First versions used the common extension \".locked\". SInce december 2019 a new version in open sourced and documented, this new version uses the \".pyza\" extension.", - "meta": { - "colt-average": "70d", - "colt-median": "66d", - "extensions": [ - ".pyza", - ".locked", - ".pysa" - ], - "ransomnotes-filenames": [ - "RECOVER_YOUR_DATA.txt" - ], - "refs": [ - "https://www.cert.ssi.gouv.fr/cti/CERTFR-2020-CTI-002/", - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2020-CTI-002.pdf", - "https://www.cert.ssi.gouv.fr/uploads/CERTFR-2020-CTI-003.pdf" - ], - "synonyms": [ - "Pyza", - "Pysa" - ] - }, - "uuid": "deed3c10-93b6-41b9-b150-f4dd1b665d87", - "value": "Mespinoza" - }, - { - "description": "A new ransomware called CoronaVirus has been distributed through a fake web site pretending to promote the system optimization software and utilities from WiseCleaner.\nWith the increasing fears and anxiety of the Coronavirus (COVID-19) outbreak, an attacker has started to build a campaign to distribute a malware cocktail consisting of the CoronaVirus Ransomware and the Kpot information-stealing Trojan.\nThis new ransomware was discovered by MalwareHunterTeam and after further digging into the source of the file, we have been able to determine how the threat actor plans on distributing the ransomware and possible clues suggesting that it may actually be a wiper.", - "meta": { - "ransomnotes-filenames": [ - "CoronaVirus.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/c/coronavirus-ransomware/ransom-note.jpg", - "https://www.bleepstatic.com/images/news/ransomware/c/coronavirus-ransomware/mbr-locker.jpg", - "https://www.bleepstatic.com/images/news/ransomware/c/coronavirus-ransomware/changed-mbrlocker-screen.jpg" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/new-coronavirus-ransomware-acts-as-cover-for-kpot-infostealer/" - ] - }, - "uuid": "575b2b3c-d762-4ba6-acbd-51ecdb57249f", - "value": "CoronaVirus" - }, - { - "description": "Snake ransomware first attracted the attention of malware analysts in January 2020 when they observed the crypto-malware family targeting entire corporate networks.\nShortly after this discovery, the threat quieted down. It produced few new detected infections in the wild for the next few months. That was until May 4, when ID Ransomware registered a sudden spike in submissions for the ransomware.", - "meta": { - "ransomnotes-filenames": [ - "Decrypt-Your-Files.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/s/SNAKE/may-2020-campaign/snake-ransom-note.jpg" - ], - "refs": [ - "https://www.cybersecurity-insiders.com/meet-the-snake-ransomware-which-encrypts-all-connected-devices/", - "https://www.tripwire.com/state-of-security/security-data-protection/massive-spike-in-snake-ransomware-activity-attributed-to-new-campaign/", - "https://www.bleepingcomputer.com/news/security/large-scale-snake-ransomware-campaign-targets-healthcare-more/" - ] - }, - "uuid": "e390e1bb-2af1-4139-8e61-6e534d707dfb", - "value": "Snake Ransomware" - }, - { - "description": "Anomali researchers have observed a new ransomware family, dubbed eCh0raix, targeting QNAP Network Attached Storage (NAS) devices. QNAP devices are created by the Taiwanese company QNAP Systems, Inc., and contain device storage and media player functionality, amongst others. The devices appear to be compromised by brute forcing weak credentials and exploiting known vulnerabilities in targeted attacks. The malicious payload encrypts the targeted file extensions on the NAS using AES encryption and appends .encrypt extension to the encrypted files. The ransom note created by the ransomware has the form shown below.\neCh0raix was first seen in June 2019, after victims began reporting ransomware attacks in a forum topic on BleepingComputer.\nOn June 1st, 2020, there has been a sudden surge of eCh0raix victims seeking help in our forums and submissions to the ransomware identification site ID-Ransomware.", - "meta": { - "extensions": [ - ".encrypt" - ], - "ransomnotes": [ - "All your data has been locked(crypted).\n​How to unclock(decrypt) instruction located in this TOR website:\nhttp://sg3dwqfpnr4sl5hh.onion/order/[Bitcoin address]\nUse TOR browser for access .onion websites.\nhttps://duckduckgo.com/html?q=tor+browser+how+to\n\nDo NOT remove this file and NOT remove last line in this file!\n[base64 encoded encrypted data]" - ], - "ransomnotes-filenames": [ - "README_FOR_DECRYPT.txt" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/ongoing-ech0raix-ransomware-campaign-targets-qnap-nas-devices/", - "https://www.anomali.com/blog/the-ech0raix-ransomware" - ] - }, - "uuid": "f3ded787-783e-4c6b-909a-8da01254380c", - "value": "eCh0raix" - }, - { - "description": "The threat group behind this malware seems to operate by hacking into companies, stealing sensitive data, and then running Egregor to encrypt all the files. According to the ransom note, if the ransom is not paid by the company within 3 days, and aside from leaking part of the stolen data, they will distribute via mass media where the company's partners and clients will know that the company was attacked.", - "meta": { - "ransomnotes-filenames": [ - "RECOVER-FILES.txt" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/columns/week-in-ransomware/2020/september/25/egregor.jpg", - "https://2kjpox12cnap3zv36440iue7-wpengine.netdna-ssl.com/wp-content/uploads/2020/10/egregor-ransom-demanding-message.png" - ], - "refs": [ - "https://www.appgate.com/news-press/appgate-labs-analyzes-new-family-of-ransomware-egregor", - "https://www.bleepingcomputer.com/news/security/crytek-hit-by-egregor-ransomware-ubisoft-data-leaked/", - "https://cybersecuritynews.com/egregor-ransomware/", - "https://securityboulevard.com/2020/10/egregor-sekhmets-cousin/" - ] - }, - "related": [ - { - "dest-uuid": "6fb1ea9e-5389-4932-8b22-c691b74b75a8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "variant-of" - }, - { - "dest-uuid": "5d999c23-11cf-4dee-84bb-f447a4f70dc8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "successor-of" - } - ], - "uuid": "8bd094a7-103f-465f-8640-18dcc53042e5", - "value": "Egregor" - }, - { - "description": "SunCrypt ransomware was discovered in October 2019 and in August 2020 it was added to Maze ransomware’s cartel. It also follows some of Maze’s tactics, techniques, and procedures. SunCrypt is launched and installed using an obfuscated PowerShell script. Infected email attachments (macros), torrent websites, malicious ads act as carriers for this ransomware.", - "meta": { - "ransomnotes-filenames": [ - "YOUR_FILES_ARE_ENCRYPTED.HTML" - ], - "ransomnotes-refs": [ - "https://www.bleepstatic.com/images/news/ransomware/s/suncrypt/maze-cartel/ransom-note.jpg" - ], - "refs": [ - "https://www.acronis.com/en-us/blog/posts/suncrypt-adopts-attacking-techniques-netwalker-and-maze-ransomware", - "https://www.bleepingcomputer.com/news/security/suncrypt-ransomware-sheds-light-on-the-maze-ransomware-cartel/", - "https://securityboulevard.com/2020/09/the-curious-case-of-suncrypt/" - ], - "synonyms": [ - "Sun", - "Suncrypt" - ] - }, - "uuid": "4fa25527-99f6-42ee-aaf2-7ca395e5fabc", - "value": "SunCrypt" - }, - { - "description": "LockBit operators tend to be very indiscriminate and opportunistic in their targeting. Actors behind this attack will use a variety of methods to gain initial access, up to and including basic methods such as brute force.\nAfter gaining initial access the actor follows a fairly typical escalation, lateral movement and ransomware execution playbook. LockBit operators tend to have a very brief dwell time, executing the final ransomware payload as quickly as they are able to. LockBit ransomware has the built-in lateral movement features; given adequate permissions throughout the targeted environment.", - "meta": { - "ransomnotes-filenames": [ - "Restore-My-Files.txt" - ], - "ransomnotes-refs": [ - "https://www.mcafee.com/wp-content/uploads/2020/04/content-in-restore-my-files.png" - ], - "refs": [ - "https://www.mcafee.com/blogs/other-blogs/mcafee-labs/tales-from-the-trenches-a-lockbit-ransomware-story/", - "https://usa.kaspersky.com/resource-center/threats/lockbit-ransomware" - ] - }, - "uuid": "8eda8bf1-db5a-412d-8511-45e2f7621d51", - "value": "LockBit" - }, - { - "description": "WastedLocker primarily targets corporate networks. Upon initial compromise, often using a fake browser update containing SocGholish, the actor then takes advantage of dual-use and LoLBin tools in an attempt to evade detection.\n Key observations include lateral movement and privilege escalation. The WastedLocker ransomware has been tied back to EvilCorp.", - "meta": { - "ransomnotes-filenames": [ - "_info" - ], - "ransomnotes-refs": [ - "https://blog.malwarebytes.com/wp-content/uploads/2020/06/ransomnote.png" - ], - "refs": [ - "https://blogs.cisco.com/security/talos/wastedlocker-goes-big-game-hunting-in-2020", - "https://blog.malwarebytes.com/threat-spotlight/2020/07/threat-spotlight-wastedlocker-customized-ransomware/", - "https://research.nccgroup.com/2020/06/23/wastedlocker-a-new-ransomware-variant-developed-by-the-evil-corp-group/" - ] - }, - "uuid": "6955c28e-e698-4bb2-8c70-ccc6d11ba1ee", - "value": "WastedLocker" - }, - { - "description": "Since this is the first detection of this malware in the wild, it’s not surprising that Babuk is not obsfuscated at all. Overall, it’s a pretty standard ransomware that utilizes some of the new techniques we see such as multi-threading encryption as well as abusing the Windows Restart Manager similar to Conti and REvil. For encrypting scheme, Babuk uses its own implementation of SHA256 hashing, ChaCha8 encryption, and Elliptic-curve Diffie–Hellman (ECDH) key generation and exchange algorithm to protect its keys and encrypt files. Like many ransomware that came before, it also has the ability to spread its encryption through enumerating the available network resources.", - "meta": { - "date": "January 2021", - "refs": [ - "http://chuongdong.com//reverse%20engineering/2021/01/03/BabukRansomware/" - ] - }, - "uuid": "c52a65d5-9bea-4a09-a81b-7f789ab48ce0", - "value": "Babuk Ranomsware" - }, - { - "description": "Darkside, the latest ransomware operation to emerge has been attacking organizations beginning earlier this month. Darkside’s customized attacks on companies have already garnered them million-dollar payouts.\nThrough their “press release”, these threat actors have claimed to be affiliated with prior ransomware operations making millions of dollars. They stated that they created this new product to match their needs, as prior products didn’t.\n Darkside explains that they only target companies they know that can pay the specified ransom. They have allegedly promised that they will not attack the following sectors. They include medicine, education, non-profit organizations, and the government sector.", - "meta": { - "colt-average": "11d", - "colt-median": "7d", - "refs": [ - "https://www.digitalshadows.com/blog-and-research/darkside-the-new-ransomware-group-behind-highly-targeted-attacks/", - "https://www.wired.com/story/ransomware-gone-corporate-darkside-where-will-it-end/", - "https://darksidedxcftmqa.onion.foundation/" - ] - }, - "uuid": "f514a46e-53ff-4f07-b75a-aed289cf221f", - "value": "Darkside" - }, - { - "description": "We recently discovered a new file-encrypting Trojan built as an ELF executable and intended to encrypt data on machines controlled by Linux-based operating systems.\nAfter the initial analysis we noticed similarities in the code of the Trojan, the text of the ransom notes and the general approach to extortion, which suggested that we had in fact encountered a Linux build of the previously known ransomware family RansomEXX. This malware is notorious for attacking large organizations and was most active earlier this year.\nRansomEXX is a highly targeted Trojan. Each sample of the malware contains a hardcoded name of the victim organization. Moreover, both the encrypted file extension and the email address for contacting the extortionists make use of the victim’s name.", - "meta": { - "extensions": [ - "", - ".", - ".", - ".txd0t", - ".dbe", - ".0s" - ], - "ransomnotes": [ - "Greetings, Texas Department of Transportation!\nRead this message CAREFULLY and contact someone from IT department..\nYour files are securely ENCRYPTED.\nNo third party decryption software EXISTS.\nMODIFICATION or RENAMING encrypted files may cause decryption failure.\nYou can send us an encrypted file (not greater than 400KB) and we will decrypt it FOR FREE, so you have no doubts in possibility to restore all Files\nFrom all aFFected systems ANY TIME.\nEncrypted File SHOULD NOT contain sensitive inFormation (technical, backups, databases, large documents).\nThe rest oF data will be available aFter the PAYMENT.\ninfrastructure rebuild will cost you MUCH more.\nContact us ONLY if you officially represent the whole affected network.\nThe ONLY attachments we accept are non archived encrypted files For test decryption.\nSpeak ENGLISH when contacting us.\nMail us: ***@protonmail.com\nWe kindly ask you not to use GMAIL, YAHOO or LIVE to contact us.\nThe PRICE depends on how quickly you do it. " - ], - "ransomnotes-filenames": [ - "TXDOT_READ_ME! .Txt", - " _READ_ME! .txt" - ], - "ransomnotes-refs": [ - "https://1.bp.blogspot.com/-hbdqo4g6OaE/XvpFV4qbjrI/AAAAAAAAT1I/RtASzBEd_VEZIhDCCCdaxrN0iGCnnocFwCLcBGAsYHQ/s1600/note-original.png", - "https://1.bp.blogspot.com/-A0tAbQoei_Y/X1UxQkema_I/AAAAAAAAVV8/QuJY6v3n6943ZFax3ztDt9FXwkpAKMPPACLcBGAsYHQ/s1600/note2-9-20.png", - "https://1.bp.blogspot.com/-RIwIgb6n0n4/X8-l2HIf88I/AAAAAAAAXRI/oyET6d1XSnwJXDIaJlwItyTFLcp4tz5mQCLcBGAsYHQ/s882/note-8-12-20.png" - ], - "refs": [ - "https://malpedia.caad.fkie.fraunhofer.de/details/win.ransomexx", - "https://id-ransomware.blogspot.com/2020/06/ransomexx-ransomware.html", - "https://github.com/Bleeping/Ransom.exx", - "https://www.bleepingcomputer.com/news/security/new-ransom-x-ransomware-used-in-texas-txdot-cyberattack/", - "https://www.bleepingcomputer.com/news/security/brazils-court-system-under-massive-ransomexx-ransomware-attack/", - "https://unit42.paloaltonetworks.com/vatet-pyxie-defray777/4/", - "https://securelist.com/ransomexx-trojan-attacks-linux-systems/99279/" - ], - "synonyms": [ - "Ransom X", - "Defray777", - "Defray-777", - "Defray 2018" - ] - }, - "uuid": "dff71334-c173-45b6-8647-af66be0605d7", - "value": "RansomEXX" - }, - { - "description": "Mobile ransomware. The Zscaler ThreatLabZ team recently came across a URL named hxxp://coronavirusapp[.]site/mobile.html, which portrays itself as a download site for an Android app that tracks the coronavirus spread across the globe. In reality, the app is Android ransomware, which locks out the victim and asks for ransom to unlock the device.\nThe app portrays itself as a Coronavirus Tracker. As soon as it starts running, it asks the user for several authorizations, including admin rights.\n In fact, this ransomware does not encrypt nor steal anything and only lock the device with an hard coded code.", - "meta": { - "ransomnotes-refs": [ - "https://www.zscaler.com/sites/default/files/images/blogs/covid/covid_lock_screen_edited_4.png", - "https://www.zscaler.com/sites/default/files/images/blogs/covid/covid_pastebin_5.png" - ], - "refs": [ - "https://www.zscaler.com/blogs/security-research/covidlock-android-ransomware-walkthrough-and-unlocking-routine" - ] - }, - "uuid": "b5fe83e9-c5d7-4b0e-99ab-4f1d356d1749", - "value": "CovidLock" - }, - { - "description": "This malware is written in Java and is named after references in the code. Tycoon has been in the wild since December 2019 and has targeted organizations in the education, SMBs, and software industries.\nTycoon is a multi-platform Java ransomware that targets Windows and Linux systems. This ransomware denies access to the system administrator following an attack on the domain controller and file servers. The initial intrusion occurs through an internet-facing remote desktop protocol (RDP) jump-server.", - "meta": { - "date": "december 2019", - "refs": [ - "https://cyberflorida.org/threat-advisory/tycoon-ransomware/", - "https://usf.app.box.com/s/83xh0t5w99klrsoisorir7kgs14o972s" - ] - }, - "uuid": "39781a7a-cd3a-4e24-aeb8-94a767a2551b", - "value": "Tycoon" - }, - { - "description": "Ragnar Locker is a ransomware identified in December 2019 that targetscorporate networks inBig Game Huntingtargeted attacks. This reportpresents recent elements regarding this ransomware.", - "meta": { - "refs": [ - "https://www.bleepingcomputer.com/news/security/ragnar-locker-ransomware-targets-msp-enterprise-support-tools/", - "https://news.sophos.com/en-us/2020/05/21/ragnar-locker-ransomware-deploys-virtual-machine-to-dodge-security/", - "https://www.cybersecurity-insiders.com/ransomware-attack-makes-cwt-pay-4-5-million-in-bitcoins-to-hackers/" - ], - "synonyms": [ - "RagnarLocker" - ] - }, - "related": [ - { - "dest-uuid": "54895630-efd2-4608-9c24-319de972a9eb", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "5d999c23-11cf-4dee-84bb-f447a4f70dc8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "related-to" - } - ], - "uuid": "e69f9836-873a-43d3-92a8-97ab783a4171", - "value": "Ragnar Locker" - }, - { - "description": "Ransom.Sekhmet not only encrypts a victims files, but also threatens to publish them.", - "meta": { - "ransomnotes-filenames": [ - "RECOVER-FILES.txt" - ], - "ransomnotes-refs": [ - "https://blog.malwarebytes.com/wp-content/uploads/2020/11/Sekhmet_ransom_note.png" - ], - "refs": [ - "https://www.bleepingcomputer.com/news/security/maze-ransomware-is-shutting-down-its-cybercrime-operation/", - "https://www.zdnet.com/article/as-maze-ransomware-group-retires-clients-turn-to-sekhmet-ransomware-spin-off-egregor/", - "https://blog.malwarebytes.com/detections/ransom-sekhmet/", - "https://securityboulevard.com/2020/10/egregor-sekhmets-cousin/" - ] - }, - "related": [ - { - "dest-uuid": "8bd094a7-103f-465f-8640-18dcc53042e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "5d999c23-11cf-4dee-84bb-f447a4f70dc8", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "successor-of" - } - ], - "uuid": "6fb1ea9e-5389-4932-8b22-c691b74b75a8", - "value": "Sekhmet" - }, - { - "description": "Ransomware", - "uuid": "79bc13e7-6e96-4974-8110-ffd8e0d12e3e", - "value": "$$$" - }, - { - "description": "Ransomware", - "uuid": "b93d2b67-aabd-4e36-a3ca-2fdfc8f0ae3b", - "value": "$ucyLocker" - }, - { - "description": "Ransomware", - "uuid": "f90db14d-e3fd-4f34-b8f8-ba82534732aa", - "value": "10001" - }, - { - "description": "Ransomware", - "uuid": "cdcf2ad5-afc3-4b7c-8d03-839e54538858", - "value": "05250lock" - }, - { - "description": "Ransomware", - "uuid": "b4c4f949-2537-47cb-8ccd-653cc37b9309", - "value": "0kilobypt" - }, - { - "description": "Ransomware", - "uuid": "a663f830-5722-4798-abcf-6c02cb5ba515", - "value": "1337-Locker" - }, - { - "description": "Ransomware", - "uuid": "0ec8cfbc-7f5b-45c6-9fc1-1bef0d8df161", - "value": "24H" - }, - { - "description": "Ransomware", - "uuid": "d76b9b9e-a265-4253-a586-3121612d5f9d", - "value": "3nCRY" - }, - { - "description": "Ransomware", - "uuid": "c36a66c0-1d52-4a2e-ad9c-1965cd18d8f8", - "value": "4rw5w" - }, - { - "description": "Ransomware", - "uuid": "a617852d-480c-4e16-8983-1ea7c2543eea", - "value": "5ss5c(5ss5cCrypt)" - }, - { - "description": "Ransomware", - "uuid": "a355ec31-a100-40f2-807b-27f3f0b71067", - "value": "777(Legion)" - }, - { - "description": "Ransomware", - "uuid": "8f63b8d3-085d-4272-88ea-bf5334f845b1", - "value": "7h9r" - }, - { - "description": "Ransomware", - "uuid": "66f8ad61-5959-4888-bafe-9f9d4868b3a9", - "value": "7z Portuguese" - }, - { - "description": "Ransomware", - "uuid": "37479546-7993-4232-9766-de19b0755bc3", - "value": "AAC" - }, - { - "description": "Ransomware", - "uuid": "461327b8-c465-4d39-8987-dbeb9e296b08", - "value": "ABCLocker" - }, - { - "description": "Ransomware", - "uuid": "4f7f33e7-ab6a-4643-aa51-da59732a6932", - "value": "Adonis" - }, - { - "description": "Ransomware", - "uuid": "4d4c478d-2349-4d1c-8693-233517d226ec", - "value": "AepCrypt" - }, - { - "description": "Ransomware", - "uuid": "c0590d85-d30d-4bf6-b245-4baeab6e6cae", - "value": "AES-Matrix" - }, - { - "description": "Ransomware", - "uuid": "adbd5acc-27d5-4483-8b9d-73cbda7498fa", - "value": "AES-NI: April Edition" - }, - { - "description": "Ransomware", - "uuid": "0c1587c6-ac37-48b5-8056-53f4fd454288", - "value": "Afrodita" - }, - { - "description": "Ransomware", - "uuid": "417027d0-15bc-497e-98a2-a1aaa328fe44", - "value": "Alco" - }, - { - "description": "Ransomware", - "uuid": "ef762a95-cb95-4a94-84df-2c083cbcf5a6", - "value": "AllCry" - }, - { - "description": "Ransomware", - "uuid": "74101521-d42c-498a-9c1c-ee31672aaba5", - "value": "AlldataLocker" - }, - { - "description": "Ransomware", - "uuid": "f8194c43-d40b-47b5-966c-99ffbafa3934", - "value": "Amnesia" - }, - { - "description": "Ransomware", - "uuid": "0372f2e5-9585-43b7-b171-d765edeedfa0", - "value": "Amnesia-2" - }, - { - "description": "Ransomware", - "uuid": "cbbf82f2-f614-4cd2-87ea-65262caa79c3", - "value": "Anatova" - }, - { - "description": "Ransomware", - "uuid": "342ab9d1-70d5-460f-8870-dc6c89037d6d", - "value": "AnDROid" - }, - { - "description": "Ransomware", - "uuid": "3d519e27-01e8-4038-9eb5-8a3155cf20a7", - "value": "AngryKite" - }, - { - "description": "Ransomware", - "uuid": "41de97ab-964c-46af-a003-b8158add1658", - "value": "AnimusLocker" - }, - { - "description": "Ransomware", - "uuid": "9659d9ea-7110-46ef-befe-a1f3c2d1ade2", - "value": "Annabelle" - }, - { - "description": "Ransomware", - "uuid": "dc5e13f7-ab37-4a4f-a3e3-65a9347e3313", - "value": "Annabelle 2.1" - }, - { - "description": "Ransomware", - "uuid": "40c30d33-3808-4b9e-a721-21cc967f7ab7", - "value": "AnonCrack" - }, - { - "description": "Ransomware", - "uuid": "5ca1e51d-4f75-471c-b6d6-0f3ab84c5945", - "value": "AnonPop" - }, - { - "description": "Ransomware", - "uuid": "2b5904c0-37f1-4e62-bdc4-2e3bdf9f8796", - "value": "AnteFrigus" - }, - { - "description": "Ransomware", - "uuid": "8d435ed6-1e4e-4082-8407-de85c715a465", - "value": "Anti-DDos" - }, - { - "description": "Ransomware", - "uuid": "2d9071ae-3e29-452a-8335-3525a5fa749e", - "value": "Antihacker2017" - }, - { - "description": "Ransomware", - "uuid": "4a03bd26-20b0-4233-b021-8e6496fc42da", - "value": "Anubi NotBTCWare" - }, - { - "description": "Ransomware", - "uuid": "cba27bf4-1275-407f-ad81-9849ba3a6f45", - "value": "Apocalypse-Missing" - }, - { - "description": "Ransomware", - "uuid": "63057077-494f-46af-b94d-902f5f526b76", - "value": "ApolloLocker" - }, - { - "description": "Ransomware", - "uuid": "c7f5c709-5624-4665-ac56-154b0e4eb594", - "value": "Argus" - }, - { - "description": "Ransomware", - "uuid": "8686cf61-5612-4e7a-8a12-cc31ee5c4daf", - "value": "Armage" - }, - { - "description": "Ransomware", - "uuid": "d2ff3b81-3d0c-471d-8f57-cfa7eaf75e7e", - "value": "Armageddon" - }, - { - "description": "Ransomware", - "uuid": "c83ea76e-b34b-47f3-a7c3-9ac4239a6d46", - "value": "ArmaLocky" - }, - { - "description": "Ransomware", - "uuid": "6219e7b3-31e6-41b7-a519-9897ebc531b6", - "value": "Arsium" - }, - { - "description": "Ransomware", - "uuid": "0065470b-3cbd-45b9-a2ea-daa688a21521", - "value": "Assembly" - }, - { - "description": "Ransomware", - "uuid": "d39b8edb-9607-4089-82f3-3a14a05cb372", - "value": "Ataware" - }, - { - "description": "Ransomware", - "uuid": "3e5f91c2-96ca-4056-9043-39fe4327828a", - "value": "Atchbo" - }, - { - "description": "Ransomware", - "uuid": "cb2d9643-46af-4512-be90-359bef60359f", - "value": "ATLAS" - }, - { - "description": "Ransomware", - "uuid": "cfba4795-cd22-4c8e-8067-9600e3cc56f4", - "value": "Australian-AES" - }, - { - "description": "Ransomware", - "uuid": "a54e8231-6665-41b4-991c-1140a5fd8d00", - "value": "AutoEncryptor" - }, - { - "description": "Ransomware", - "uuid": "57970f54-2957-444d-a60d-5c10f129064c", - "value": "AutoWannaCryV2" - }, - { - "description": "Ransomware", - "uuid": "5225f660-288c-4e30-829c-a61d732ff10a", - "value": "Auuahk-Ouuohk" - }, - { - "description": "Ransomware", - "uuid": "61fc0258-6fd5-481c-b044-2b5e22185049", - "value": "AVCrypt" - }, - { - "description": "Ransomware", - "uuid": "1ee82db5-c1f6-4b2c-96d0-e2f9519e5406", - "value": "AxCrypter" - }, - { - "description": "Ransomware", - "uuid": "71eef963-71ad-4641-9e73-3f78a5e2891c", - "value": "aZaZeL" - }, - { - "description": "Ransomware", - "uuid": "281091db-9517-4ac0-9315-6846f85c567f", - "value": "BadEncript" - }, - { - "description": "Ransomware", - "uuid": "76d8ccdb-37cf-4eb7-bb64-d3b48b0dfc89", - "value": "Balbaz" - }, - { - "description": "Ransomware", - "uuid": "3d0b5aa1-3164-4db8-8c87-ced896784ab5", - "value": "Baliluware" - }, - { - "description": "Ransomware", - "uuid": "dfce034f-30b2-4761-b55e-e88cafb4526a", - "value": "Bam!" - }, - { - "description": "Ransomware", - "uuid": "7f156e6d-7612-4e74-a5af-a53ea6d19b01", - "value": "BananaCrypt" - }, - { - "description": "Ransomware", - "uuid": "ac962a32-e2d2-4e64-ab29-524d570a0dcd", - "value": "BancoCrypt HT" - }, - { - "description": "Ransomware", - "uuid": "e65f4496-0560-49ba-b52a-30df8f1a0d44", - "value": "Barack Obama's EBBV" - }, - { - "description": "Ransomware", - "uuid": "834bd641-fb8e-40b7-a310-da6aa3f67399", - "value": "Basilisque Locker" - }, - { - "description": "Ransomware", - "uuid": "736f68d4-9a7f-488d-a8ff-7fd4988c6399", - "value": "BASS-FES" - }, - { - "description": "Ransomware", - "uuid": "d1846b2a-6017-4c18-8e7d-edcf831ada71", - "value": "BB" - }, - { - "description": "Ransomware", - "uuid": "0854242f-a664-43bf-b13f-d0e4b718c7b4", - "value": "BeethoveN" - }, - { - "description": "Ransomware", - "uuid": "aecde5c7-0d8b-41a3-9772-0aba95d87fac", - "value": "BestChangeRu" - }, - { - "description": "Ransomware", - "uuid": "dda4fb07-113a-4feb-81e5-c04c35addcd3", - "value": "BigBossHorse" - }, - { - "description": "Ransomware", - "uuid": "abc0f12a-0414-4049-8ee7-90bc1d5d98d9", - "value": "Birbware" - }, - { - "description": "Ransomware", - "uuid": "4be6c6d2-3417-41ce-8334-c31811c161db", - "value": "BitCrypt" - }, - { - "description": "Ransomware", - "uuid": "06d438c7-81fa-4c2e-8a48-bd8e3d63a946", - "value": "BitCrypt 2.0" - }, - { - "description": "Ransomware", - "uuid": "5b45c3e8-7d91-41d4-a7d3-a7bbb0ebdd83", - "value": "BitKangoroo" - }, - { - "description": "Ransomware", - "uuid": "f66ac6a3-e71c-4cf8-ac5b-02ca80749252", - "value": "BitPyLock" - }, - { - "description": "Ransomware", - "uuid": "e92e4a0e-7fdb-482a-8ff9-3fa36eb0ca95", - "value": "Bitshifter" - }, - { - "description": "Ransomware", - "uuid": "b7f51df4-138c-47fb-8c74-419478cc8cba", - "value": "BKRansomware" - }, - { - "description": "Ransomware", - "uuid": "47fcb57a-4d58-46df-a3f1-3c621c9c5508", - "value": "Black Feather" - }, - { - "description": "Ransomware", - "uuid": "353e2676-d8c0-4e2b-bf7b-b12aaada96cf", - "value": "BlackFireEye" - }, - { - "description": "Ransomware", - "uuid": "85fcfa86-65bc-4c35-8584-1f0515a61df3", - "value": "BlackHat-Mehtihack" - }, - { - "description": "Ransomware", - "uuid": "6dccf9ae-d58d-4a45-baaf-cd873a2fd7bc", - "value": "BlackKingdom" - }, - { - "description": "Ransomware", - "uuid": "a57d5a37-c3fc-4c26-aac0-0803d4ef8adb", - "value": "BlackMist" - }, - { - "description": "Ransomware", - "uuid": "b05ae01a-bcc4-4642-a165-40b503ad260f", - "value": "Blackout" - }, - { - "description": "Ransomware", - "uuid": "3485d93d-c6cd-4a45-85c9-6e3cda016ae6", - "value": "BlackPink" - }, - { - "description": "Ransomware", - "uuid": "01fcca8a-a5b7-4683-b457-66a720f6e569", - "value": "BlackRose" - }, - { - "description": "Ransomware", - "uuid": "8fba79e8-a902-4fbe-8c84-67e2b266ddb6", - "value": "BlackSheep" - }, - { - "description": "Ransomware", - "uuid": "14e57527-58cc-4e0a-8e14-9f00a0167610", - "value": "Black Worm" - }, - { - "description": "Ransomware", - "uuid": "0ac4a0b6-c4db-408d-8b0d-7bd4fa7d9c5d", - "value": "Blank" - }, - { - "description": "Ransomware", - "uuid": "1edc8d40-837b-4ec2-9be4-15c63d5dd266", - "value": "Blind" - }, - { - "description": "Ransomware", - "uuid": "11a5a5ac-91f6-41b0-a4c9-010d7754f938", - "value": "Blitzkrieg" - }, - { - "description": "Ransomware", - "uuid": "cda890bf-1d9e-4566-9bc7-3bb4cd3ee571", - "value": "BlockFile12" - }, - { - "description": "Ransomware", - "uuid": "a79b56a9-50e7-42c4-b8b6-fda1fa2dc097", - "value": "BloodJaws" - }, - { - "description": "Ransomware", - "uuid": "01ef6f02-22e4-478f-b02f-6515caf078e3", - "value": "Blooper" - }, - { - "description": "Ransomware", - "uuid": "147e865d-90f6-4332-bdad-967ea69a4b11", - "value": "BlueCheeser" - }, - { - "description": "Ransomware", - "uuid": "3c40df84-ef3b-4f59-86ed-a7a6acd0d902", - "value": "Bluerose" - }, - { - "description": "Ransomware", - "uuid": "13f3e911-757c-401f-b2c9-fedf7f089d3f", - "value": "BOK" - }, - { - "description": "Ransomware", - "uuid": "0c9f224c-2649-4aa7-bdce-fd8655b1fe92", - "value": "BoooamCrypt" - }, - { - "description": "Ransomware", - "uuid": "88533a36-b417-4a90-888e-a4a70dab39fe", - "value": "BooM" - }, - { - "description": "Ransomware", - "uuid": "12007b9f-af6b-4dcd-ac50-99154b1045be", - "value": "Boris HT" - }, - { - "description": "Ransomware", - "uuid": "c316df34-8f12-49ef-9534-b28b640047cc", - "value": "BrainLag" - }, - { - "description": "Ransomware", - "uuid": "3e83ee9d-bfc7-49bf-9ecf-6185d887b51e", - "value": "BRansomware" - }, - { - "description": "Ransomware", - "uuid": "b1298047-13af-4241-b491-305ceb5af7e7", - "value": "Brick" - }, - { - "description": "Ransomware", - "uuid": "74284a53-0078-4819-817a-2283ff04e9d8", - "value": "BrickR" - }, - { - "description": "Ransomware", - "uuid": "8903296a-2ebb-4ec6-97e4-2379348906ff", - "value": "BtcKING" - }, - { - "description": "Ransomware", - "uuid": "52ce04e8-c764-4ded-8df6-f3df15a5b117", - "value": "BTCWare-Aleta" - }, - { - "description": "Ransomware", - "uuid": "d11b8d25-7731-43e6-8880-4ed6bc4d66cd", - "value": "BTCWare-Gryphon" - }, - { - "description": "Ransomware", - "uuid": "6416e35d-8507-4144-b1ad-323161f25217", - "value": "BTCWare-Master" - }, - { - "description": "Ransomware", - "uuid": "a8bd5e60-954c-463d-94b6-a76c45310f6b", - "value": "BTCWare-Nuclear" - }, - { - "description": "Ransomware", - "uuid": "670eec47-c2ae-491d-b102-328866b8a312", - "value": "BTCWare-Onyon" - }, - { - "description": "Ransomware", - "uuid": "7c37c90b-7750-4f5f-ba64-3f058ac83788", - "value": "BTCWare-PayDay" - }, - { - "description": "Ransomware", - "uuid": "f6246bb2-bb04-43ef-acbf-f88b5bc78440", - "value": "BTCWare-Wyvern" - }, - { - "description": "Ransomware", - "uuid": "4f0ddce5-6f85-4f76-b93a-48e15d45f211", - "value": "Bud" - }, - { - "description": "Ransomware", - "uuid": "80b3b6cd-9cc7-4a98-b342-c83d7a167abf", - "value": "BugWare" - }, - { - "description": "Ransomware", - "uuid": "d3fdd556-cfb4-4aba-b4a9-6698a95cd17c", - "value": "BulbaCrypt HT" - }, - { - "description": "Ransomware", - "uuid": "ce6c2b29-8195-4754-ae24-2e1321764afe", - "value": "BWall" - }, - { - "description": "Ransomware", - "uuid": "cafacee4-da55-4ec0-ae5c-f7b9d80d0ebf", - "value": "C0hen Locker" - }, - { - "description": "Ransomware", - "uuid": "d56bd7ad-8620-407f-9429-0ff3a0b106b9", - "value": "CA$HOUT" - }, - { - "description": "Ransomware", - "uuid": "708623d0-bbc7-4a8c-9ef8-0266fbf44196", - "value": "CainXPii" - }, - { - "description": "Ransomware", - "uuid": "5261a5d0-a1b0-46f4-b5ae-f32e2728b1cb", - "value": "Cephalo" - }, - { - "description": "Ransomware", - "uuid": "cabe1175-a46b-47e4-9d25-655af0411208", - "value": "Cerberos" - }, - { - "description": "Ransomware", - "uuid": "1fc9a816-ba8d-4811-b930-e2b3c732566f", - "value": "Charmant" - }, - { - "description": "Ransomware", - "uuid": "c9bc4999-a62e-46d5-b0a2-56de5fcde9d5", - "value": "Chekyshka" - }, - { - "description": "Ransomware", - "uuid": "cabdc3c6-17cc-43f1-b469-2372be8d9474", - "value": "ChernoLocker" - }, - { - "description": "Ransomware", - "uuid": "cfd553d0-385b-459a-bc24-dee116249614", - "value": "ChinaYunLong" - }, - { - "description": "Ransomware", - "uuid": "8b644615-af51-4f46-ad09-68274e48ce2b", - "value": "Christmas" - }, - { - "description": "Ransomware", - "uuid": "b87bf395-3e4f-4b2b-bad5-ac88a6c19741", - "value": "ClicoCrypter" - }, - { - "description": "Ransomware", - "uuid": "5a4c04f0-0d05-4068-ba64-bd4979b58d5c", - "value": "ClicoCrypter-2" - }, - { - "description": "Ransomware", - "uuid": "81b6aafe-7b16-4d86-94d7-23fc172d0b81", - "value": "Clouded" - }, - { - "description": "Ransomware", - "uuid": "5f784db9-36e0-4763-aebc-474b53558cef", - "value": "Cmd" - }, - { - "description": "Ransomware", - "uuid": "9bb10b99-a440-4dea-905c-87e95e13e1ae", - "value": "Codemanager" - }, - { - "description": "Ransomware", - "uuid": "905eb47a-0494-402b-ac95-ad201627ff20", - "value": "Coin Locker" - }, - { - "description": "Ransomware", - "uuid": "d3b9dd33-3928-4999-8934-aff1ec1fc1a8", - "value": "Comrade HT" - }, - { - "description": "Ransomware", - "uuid": "e0d382e1-0ad3-476e-a953-e7f53c42a703", - "value": "CoNFicker" - }, - { - "description": "Ransomware", - "uuid": "3f3bdf79-67c9-41f5-bc26-398b11cc9551", - "value": "Coom" - }, - { - "description": "Ransomware", - "uuid": "66f35862-3f0c-4328-a792-12e90b6baca8", - "value": "CorruptCrypt" - }, - { - "description": "Ransomware", - "uuid": "5dc6d20f-db0c-44e9-95a3-ee4adb1aa3ad", - "value": "Creeper" - }, - { - "description": "Ransomware", - "uuid": "a3ff8fe7-54b5-4404-b7b7-cf823027e647", - "value": "Creepy" - }, - { - "description": "Ransomware", - "uuid": "8d927c7b-2526-4cf4-a3e6-093f929fa264", - "value": "Cripton" - }, - { - "description": "Ransomware", - "uuid": "5470834d-dc90-492f-8ed8-666c40911515", - "value": "Cripton7zp" - }, - { - "description": "Ransomware", - "uuid": "d4a347c9-6f9b-4578-b7d2-fdcbc0c04d1d", - "value": "Cry36" - }, - { - "description": "Ransomware", - "uuid": "67543823-e4d9-4321-82a0-06820f6cc3e0", - "value": "Cry9" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "PayPalGenerator2019" - ] - }, - "uuid": "92ca663a-347a-47d7-b7da-1208b84a7217", - "value": "CryCipher" - }, - { - "description": "Ransomware", - "uuid": "381ef192-e5ee-4d58-86a3-de853837cb9e", - "value": "CryForMe" - }, - { - "description": "Ransomware", - "uuid": "654fdcba-0432-42e4-9ca9-8b89dd9f0d98", - "value": "Crying" - }, - { - "description": "Ransomware", - "uuid": "4b7d257a-db3a-418a-a295-56ead7fa573c", - "value": "CryMore" - }, - { - "description": "Ransomware", - "uuid": "b08ca08b-7561-4425-95c7-aa01589022cf", - "value": "Cryp70n1c" - }, - { - "description": "Ransomware", - "uuid": "56cdf22e-2c02-4413-9d5f-e30d458c995c", - "value": "Crypt0 HT" - }, - { - "description": "Ransomware", - "uuid": "be108e7d-d3d8-4e21-88d7-093d4674eb88", - "value": "Crypt0" - }, - { - "description": "Ransomware", - "uuid": "e4f33b48-653a-4d11-94fd-16d81360e2af", - "value": "Crypt0L0cker" - }, - { - "description": "Ransomware", - "uuid": "b4841b77-1f57-4d7a-8801-1808ca291cfc", - "value": "Crypt0r" - }, - { - "description": "Ransomware", - "uuid": "291daba8-62d3-4bd0-bcfa-68dcba4425c5", - "value": "Crypt12" - }, - { - "description": "Ransomware", - "uuid": "5a23ab82-e373-4429-99e9-743119000dea", - "value": "CryptFuck" - }, - { - "description": "Ransomware", - "uuid": "d07b4335-f967-4e82-80dd-861cd3864c28", - "value": "CryptGh0st" - }, - { - "description": "Ransomware", - "uuid": "6181604f-86e3-4aca-acd1-e715092a5f0f", - "value": "Crypto_Lab" - }, - { - "description": "Ransomware", - "uuid": "7864b740-8f71-43f0-afa8-585a12dd7a8b", - "value": "CryptoApp" - }, - { - "description": "Ransomware", - "uuid": "bb0e8fd4-e737-4781-860c-9f97fc7724b6", - "value": "Crypto-Blocker" - }, - { - "description": "Ransomware", - "uuid": "5ba61618-2e80-4330-88ef-101c5c1d8432", - "value": "CryptoBoss" - }, - { - "description": "Ransomware", - "uuid": "72be1360-a686-4f32-8179-a2a466d0898e", - "value": "CryptoCat" - }, - { - "description": "Ransomware", - "uuid": "876c1bbb-0723-46b2-92a2-1fe0917e432a", - "value": "CryptoClone" - }, - { - "description": "Ransomware", - "uuid": "be33ab7d-d272-4430-8e8c-7fdbd379e188", - "value": "CryptoDark" - }, - { - "description": "Ransomware", - "uuid": "4a9a48f2-5aa9-4a3c-9c7a-928ee513abf2", - "value": "CryptoGod 2017" - }, - { - "description": "Ransomware", - "uuid": "5360787b-68b8-4827-a38e-af04ae150943", - "value": "CryptoGod 2018" - }, - { - "description": "Ransomware", - "uuid": "0cb45ddc-d7c7-42b8-b006-3aecff1d5ebc", - "value": "CryptoLite" - }, - { - "description": "Ransomware", - "uuid": "97320061-1478-486c-ba54-62018fe31fdb", - "value": "CryptolockerEmulator" - }, - { - "description": "Ransomware", - "uuid": "ca054485-d14d-45df-92ae-47b9b4dbc4c7", - "value": "CryptoLockerEU 2016" - }, - { - "description": "Ransomware", - "uuid": "8538f7d6-9fcb-4070-bb0c-aff7bb7874f1", - "value": "CryptoManiac" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "value": "CryptoMix-0000" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "value": "CryptoMix-Arena" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "value": "CryptoMix-Azer" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "value": "CryptoMix-Backup" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "value": "CryptoMix-CK" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "value": "CryptoMix-Coban" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "value": "CryptoMix-DLL" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "value": "CryptoMix-Empty" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "value": "CryptoMix-Error" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "value": "CryptoMix-Exte" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "value": "Cryptomix-FILE" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "value": "CryptoMix-MOLE66" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "value": "CryptoMix-Noob" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "value": "CryptoMix-Ogonia" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "value": "CryptoMix-Pirate" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "value": "CryptoMix-Revenge" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "SERVER Cryptomix" - ] - }, - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "value": "Cryptomix-SERVER" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "Shark CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "value": "CryptoMix-Shark" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "System CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "value": "CryptoMix-System" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "Tastylock CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "value": "CryptoMix-Tastylock" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "Test CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "c76110ea-15f1-4adf-a28d-c707374dbb3a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "value": "CryptoMix-Test" - }, - { - "description": "Ransomware", - "related": [ - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "value": "CryptoMix-Wallet" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "WORK CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "value": "Cryptomix-WORK" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "x1881 CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "value": "CryptoMix-x1881" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "XZZX CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "value": "CryptoMix-XZZX" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "Zayka CryptoMix" - ] - }, - "related": [ - { - "dest-uuid": "20b848d1-3f21-403b-a4c8-c5d2a89faeb9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "771706fa-1015-4bcd-9a74-293285fcd051", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ecaef53f-a4a2-4360-b8e1-cca7b606596a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "2fec3512-9782-4b3b-a880-30fda4641858", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "8c484784-308a-498f-948b-bc5df8ba4725", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "aabd25a5-021a-49db-bda8-a922f41c678c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "c1092c4f-91a1-469a-a144-c5d10a94fed6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "86d45c08-bb85-4d0f-a5d5-3d73d65bd2e5", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "41d393ee-a8ee-4a9d-b510-e1b6a59054f9", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ea68b5a8-6f9e-441a-a308-5e4fda8dbab6", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "26fa33ba-528c-49f8-94c2-db4047a37bd0", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d61b7ace-ba80-4d79-9ff2-b6f80af5770b", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "ef2f721b-0bc0-4f2a-8803-263368fa467d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "3c3b5442-f81f-4011-a176-f0f63e6fcd3f", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "312c93ae-9405-445b-be11-2d0e4aec4f84", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "6a8ed1dd-34f1-42a3-9d9a-f81d91f53f7c", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "460e3f42-15dc-4e73-ad39-76af8d272379", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "fc5ee56f-3cd1-4120-9b33-48993987d98d", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "00ca9891-c7dd-44db-a374-14b92169741a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "d8fcab2d-f80c-4165-88f5-db29f7aa1087", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "a4bac628-162c-4487-9bb5-c34e42dec72a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "51b0559d-547f-40c0-850a-df9f67c08baf", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "99c5cbdd-9c04-4c18-bcdd-9ee9b4dba862", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "b55c38f8-b369-4f91-904c-b0758927bd99", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - }, - { - "dest-uuid": "e1eea458-c466-48d8-a121-f5fe14a1cc75", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "548e3dcd-8448-4318-830a-b8fa46f34fd3", - "value": "CryptoMix-Zayka" - }, - { - "description": "Ransomware", - "uuid": "19d80d86-1f3d-47b5-82f1-5c2b3ab279d8", - "value": "Crypton" - }, - { - "description": "Ransomware", - "uuid": "02fef633-e89f-43f5-bf52-a4e18f670a2d", - "value": "CryptoPatronum" - }, - { - "description": "Ransomware", - "uuid": "334525f2-9e02-4d7e-b866-6a950341b848", - "value": "CryptoPokemon" - }, - { - "description": "Ransomware", - "uuid": "d5ccf284-90c3-44b6-9b90-ddc4717defac", - "value": "CryptorBit" - }, - { - "description": "Ransomware", - "uuid": "b1a948b2-d072-47d3-9512-e22fe8fb9fb1", - "value": "CryptoShield 2.0" - }, - { - "description": "Ransomware", - "uuid": "e28ac7f9-cb1e-4e28-aace-27162529e96c", - "value": "CryptoSpider" - }, - { - "description": "Ransomware", - "uuid": "84a6d707-6163-4c05-a3a2-d5c605cb6267", - "value": "CryptoViki" - }, - { - "description": "Ransomware", - "uuid": "6260f9a3-b4c6-4f0b-910f-c98c3a13a2de", - "value": "Cryptre" - }, - { - "description": "Ransomware", - "uuid": "39f15885-0ef0-4f04-a837-f1da4b4813bc", - "value": "CrypTron" - }, - { - "description": "Ransomware", - "uuid": "d757c892-1d05-41f7-9aec-cb9f72316432", - "value": "Crysis XTBL" - }, - { - "description": "Ransomware", - "uuid": "bfd0bcdc-3cc6-4d4b-bf5c-e1467e985610", - "value": "Crystal" - }, - { - "description": "Ransomware", - "uuid": "e64a7cc3-2454-4e77-8fd9-ed12d854e2dd", - "value": "CrystalCrypt" - }, - { - "description": "Ransomware", - "uuid": "e429df1e-ee56-48ff-801f-5648ce9b47cb", - "value": "CryTekk" - }, - { - "description": "Ransomware", - "uuid": "76b33701-ac6e-4ef1-95b8-b7e18204b901", - "value": "CSP" - }, - { - "description": "Ransomware", - "uuid": "1fda05ea-74c7-4942-ac5d-0d9b6adc4eed", - "value": "CTB-Locker Original" - }, - { - "description": "Ransomware", - "uuid": "ce5eb940-5fd6-4d2f-bfa8-2191ae3e4239", - "value": "CTF" - }, - { - "description": "Ransomware", - "uuid": "2a95f6b9-3ce7-40b9-bda8-0832e0d9d07f", - "value": "Cuba" - }, - { - "description": "Ransomware", - "uuid": "ed087a5a-41f7-4997-9701-ef46c984d89d", - "value": "Curumim" - }, - { - "description": "Ransomware", - "uuid": "6cd337d7-b073-4950-afe9-8979151137ae", - "value": "CVLocker" - }, - { - "description": "Ransomware", - "uuid": "a255f8e2-5ffa-4b4e-91b7-f5620cf8a2ea", - "value": "Cyber Police HT" - }, - { - "description": "Ransomware", - "uuid": "6b6d567b-dcaf-4ebd-b3c7-d81ecaf6e820", - "value": "CyberDrill2" - }, - { - "description": "Ransomware", - "uuid": "59dc87a1-e66f-48a3-8eb9-9591b3c8339b", - "value": "CyberResearcher" - }, - { - "description": "Ransomware", - "uuid": "b9a0558f-b975-4406-8381-7e93e2d96394", - "value": "CyberSCCP" - }, - { - "description": "Ransomware", - "uuid": "3a69e0f9-ef7e-418e-87f5-821b5f7c7d3d", - "value": "CyberSoldier" - }, - { - "description": "Ransomware", - "uuid": "67e652fe-2689-41f1-b7fe-1550ec3031ab", - "value": "Cyclone" - }, - { - "description": "Ransomware", - "uuid": "d1ed0b02-020f-467f-9b4b-4c1c910257a2", - "value": "CypherPy" - }, - { - "description": "Ransomware", - "uuid": "bb8b3841-4e99-4114-b640-00dfef8206cf", - "value": "Cyspt" - }, - { - "description": "Ransomware", - "uuid": "b536d9b6-f3b6-446d-94d7-a6ac36f2ecf8", - "value": "Czech" - }, - { - "description": "Ransomware", - "uuid": "8971edef-7b24-4682-8a6e-9aff32778ebf", - "value": "D00mEd" - }, - { - "description": "Ransomware", - "uuid": "fcf7240e-7d1b-4b0d-84b8-7ab0919b5444", - "value": "D2+D" - }, - { - "description": "Ransomware", - "uuid": "15d3732d-5ca8-4dc4-bf9b-8f7791706d17", - "value": "DarkKomet" - }, - { - "description": "Ransomware", - "uuid": "a3e8d4f9-d24d-40de-9ba9-256774da6d17", - "value": "DarkLocker" - }, - { - "description": "Ransomware", - "uuid": "27d38148-e9d4-4b4b-8b7b-514060493a40", - "value": "DarkoderCryptor" - }, - { - "description": "Ransomware", - "uuid": "4c90d525-b24f-43b5-941e-2bc3038669ff", - "value": "DataKeeper" - }, - { - "description": "Ransomware", - "uuid": "0f22483f-8227-4977-8097-55d5f3971a32", - "value": "Datebatut" - }, - { - "description": "Ransomware", - "uuid": "3f550aa8-f9ec-4040-be24-1182c0f6637f", - "value": "DCRTR" - }, - { - "description": "Ransomware", - "uuid": "3b0aa35a-b0f7-4263-b7a6-50efdb5b4c42", - "value": "DCRTR-WDM" - }, - { - "description": "Ransomware", - "uuid": "25d55a0a-7a5c-4ce2-be3e-7fda4be4cfe6", - "value": "DCry" - }, - { - "description": "Ransomware", - "uuid": "6bc76688-d22f-414b-8019-a4e22d76a662", - "value": "DDE" - }, - { - "description": "Ransomware", - "uuid": "7af4bdcb-bfeb-4ad1-8b6c-eae6df8f81b0", - "value": "DeadSec-Crypto" - }, - { - "description": "Ransomware", - "uuid": "ee027575-6c9e-4803-80fa-6ff4f4d0af68", - "value": "DeathHiddenTear (Large&Small HT) > " - }, - { - "description": "Ransomware", - "uuid": "101c648e-8c7a-4082-902f-37a536c38063", - "value": "DeathNote" - }, - { - "description": "Ransomware", - "uuid": "b4ad80c6-1a90-4f20-a3e2-8e127a295861", - "value": "DeathRansom" - }, - { - "description": "Ransomware", - "uuid": "8c7cd622-c0cb-4d4a-991b-99de948baf8d", - "value": "DecryptIomega" - }, - { - "description": "Ransomware", - "uuid": "b298b00f-1cc9-4b08-b2a2-8b16cafdee73", - "value": "Decryption Assistant" - }, - { - "description": "Ransomware", - "uuid": "54a0441c-c25d-4a7a-b572-2a8fb1d91a61", - "value": "DecService" - }, - { - "description": "Ransomware", - "uuid": "89f73121-682a-4675-815e-af3b3183c000", - "value": "DecYourData" - }, - { - "description": "Ransomware", - "uuid": "d14aacd7-dea9-44ea-8160-ffee220fb572", - "value": "Defender" - }, - { - "description": "Ransomware", - "uuid": "ca4b65f9-b49e-4531-90a9-4448e0a1fbce", - "value": "Defray (Glushkov)" - }, - { - "description": "Ransomware", - "uuid": "fac72d3c-e12e-4ec0-8006-176d2f10df56", - "value": "Deos" - }, - { - "description": "Ransomware", - "uuid": "8fab2ebc-526e-46ce-9f32-4ae06337acd4", - "value": "Desktop" - }, - { - "description": "Ransomware", - "uuid": "e2a2169c-73ac-4ee3-aa0d-05c00fffd9f2", - "value": "Diamond" - }, - { - "description": "Ransomware", - "uuid": "1435b9b7-2c3d-4f0d-b651-617b67877273", - "value": "DilmaLocker" - }, - { - "description": "Ransomware", - "uuid": "a3ea2517-9e89-4088-9433-6091f29b8a22", - "value": "Dishwasher" - }, - { - "description": "Ransomware", - "uuid": "b28aa31f-32cf-44eb-ae6f-2d952b1e9a01", - "value": "District" - }, - { - "description": "Ransomware", - "uuid": "517622cc-b402-4791-b5cd-b793f7bcf232", - "value": "DMA Locker 1.0-2.0-3.0" - }, - { - "description": "Ransomware", - "uuid": "0a852768-faaa-4e9f-88b4-cdc8887a4518", - "value": "DMA Locker 4.0" - }, - { - "description": "Ransomware", - "uuid": "b7a27265-4300-401b-b8e4-82ec20cea5f9", - "value": "DMALocker Imposter" - }, - { - "description": "Ransomware", - "uuid": "0416d649-c1e1-4e52-9b02-dd78dc4829ba", - "value": "Dodger" - }, - { - "description": "Ransomware", - "uuid": "29d2e73b-dda0-4206-9c45-597dd2fd2c81", - "value": "DolphinTear" - }, - { - "description": "Ransomware", - "uuid": "dec37a2c-1f82-4a42-9ac4-1cbadcec28a7", - "value": "Donald Trump" - }, - { - "description": "Ransomware", - "uuid": "abb380f4-1237-421f-8b34-5616acdabdfb", - "value": "Donation1" - }, - { - "description": "Ransomware", - "uuid": "2e8f75c9-5122-4f5d-a32d-c6b500f7cd28", - "value": "Done" - }, - { - "description": "Ransomware", - "uuid": "177d029a-4414-4300-8ef3-2dd476f006e9", - "value": "Dont_Worry" - }, - { - "description": "Ransomware", - "uuid": "d029f838-1bf1-4a35-bd7c-43bd0a513693", - "value": "DotNoData" - }, - { - "description": "Ransomware", - "uuid": "bbb53d99-09e9-42a9-812e-96539da0ed4b", - "value": "DotZeroCMD" - }, - { - "description": "Ransomware", - "uuid": "b544ea57-deee-4e66-91c4-b4d02a9e283e", - "value": "Dr. Fucker" - }, - { - "description": "Ransomware", - "uuid": "10731cae-b25b-49a7-b821-c4b655e99a38", - "value": "Dr. Jimbo" - }, - { - "description": "Ransomware", - "uuid": "099c3512-a86b-40dc-94f9-7f2052991212", - "value": "Drakos" - }, - { - "description": "Ransomware", - "uuid": "68b0ba66-0c9e-4ae2-856d-d43c024c5e0c", - "value": "DriedSister" - }, - { - "description": "Ransomware", - "uuid": "c14d0a23-5394-4a51-b3d6-7602b4b8d6ac", - "value": "Dviide" - }, - { - "description": "Ransomware", - "uuid": "bfd3bb40-5057-4774-983f-1d61ab5fd38d", - "value": "eBayWall" - }, - { - "description": "Ransomware", - "uuid": "1222a73b-6ae7-4e21-9fd0-df2ddc2d9ef3", - "value": "EbolaRnsmwr" - }, - { - "description": "Ransomware", - "uuid": "19638b5e-cfc9-4bbd-9f21-0efc7cd1929a", - "value": "ECLR" - }, - { - "description": "Ransomware", - "uuid": "b166020d-baac-4424-ab13-fbdfcd52dee5", - "value": "EggLocker" - }, - { - "description": "Ransomware", - "uuid": "1c8c31ef-0d95-4e70-baf2-7d85fa46f1fd", - "value": "Ekati demo tool" - }, - { - "description": "Ransomware", - "uuid": "5f47e7f6-b872-443c-83d5-5993dca85e0b", - "value": "Enc1" - }, - { - "description": "Ransomware", - "uuid": "a24aee63-5e3c-4aec-a79d-6cb3cf2ee7a5", - "value": "EncoderCSL" - }, - { - "description": "Ransomware", - "uuid": "8856e9e4-4774-44af-a89c-00ee64af95b3", - "value": "EnCrypt" - }, - { - "description": "Ransomware", - "uuid": "7f2f2f1c-43ec-40a4-92f3-e6b27a86fd66", - "value": "EncryptedBatch" - }, - { - "description": "Ransomware", - "uuid": "cb1db616-8c54-46c9-9a54-c59b0f34203e", - "value": "EncryptServer2018" - }, - { - "description": "Ransomware", - "uuid": "049a556e-143c-4ed4-a1d5-b32a5818e3f5", - "value": "EnybenyCrypt" - }, - { - "description": "Ransomware", - "uuid": "44816458-fbf1-46f5-9189-031a4f5a9494", - "value": "EOEO" - }, - { - "description": "Ransomware", - "uuid": "34b549c2-e28f-475c-916e-d164b7d984bf", - "value": "Epoblockl" - }, - { - "description": "Ransomware", - "uuid": "50a03182-fb83-4d2d-a33b-13bbab4f9c94", - "value": "Erica2020" - }, - { - "description": "Ransomware", - "uuid": "1d48b852-ddb9-4294-9502-244b2664fe0c", - "value": "Eris" - }, - { - "description": "Ransomware", - "uuid": "35275d91-8878-45fd-aa11-d5932a4a3707", - "value": "Estemani" - }, - { - "description": "Ransomware", - "uuid": "b1fe23d0-e3f3-4164-ab96-4e859a25e639", - "value": "Eternal" - }, - { - "description": "Ransomware", - "uuid": "97c7c06d-e2b6-459c-92ec-bde5a4dd54ff", - "value": "Eternity" - }, - { - "description": "Ransomware", - "uuid": "4b7906b7-1e17-4c5d-a56f-abf238e42dcf", - "value": "Euclid" - }, - { - "description": "Ransomware", - "uuid": "6287e47b-7919-4be1-9ee8-c3a9a7f0feab", - "value": "Evasive HT" - }, - { - "description": "Ransomware", - "uuid": "47554d81-a6d9-4017-ad8c-cab653e6a1b3", - "value": "Evolution" - }, - { - "description": "Ransomware", - "uuid": "803671d5-8d84-45c9-aef0-13dbaedd2b4c", - "value": "Executioner" - }, - { - "description": "Ransomware", - "uuid": "ed1bebe5-6bad-448c-8b92-ca7fd8563a2b", - "value": "ExecutionerPlus" - }, - { - "description": "Ransomware", - "uuid": "23fe7df3-ad1b-4270-b519-3d7db4d62d0b", - "value": "Exocrypt XTC" - }, - { - "description": "Ransomware", - "uuid": "89aed7ce-b8db-4d66-91b3-cae5def39255", - "value": "ExoLock" - }, - { - "description": "Ransomware", - "uuid": "80304c6b-de78-4db0-a0b9-7e3164f818d2", - "value": "ExpBoot" - }, - { - "description": "Ransomware", - "uuid": "7b9fa522-8db4-4b29-adcf-7c01c21c39b4", - "value": "Explorer" - }, - { - "description": "Ransomware", - "meta": { - "synonyms": [ - "Sextortion Scam" - ] - }, - "uuid": "08890a08-8ffc-49f5-b5b9-6a89002327f3", - "value": "Extortion Scam" - }, - { - "description": "Ransomware", - "uuid": "59c28ba7-d42a-42d8-afaa-69fcbe9eaadb", - "value": "Extractor" - }, - { - "description": "Ransomware", - "uuid": "a6ef13a1-5429-47eb-8d8b-5ffde2ebdff0", - "value": "EyLamo" - }, - { - "description": "Ransomware", - "uuid": "919cadc1-9089-4fd4-a8d9-c83089f78391", - "value": "EZDZ" - }, - { - "description": "Ransomware", - "uuid": "0c22c2e4-f83e-4f16-841c-534d569a1b30", - "value": "Fabiansomware" - }, - { - "description": "Ransomware", - "uuid": "7ccbce77-7251-451f-ba92-da1439a916d0", - "value": "Facebook HT" - }, - { - "description": "Ransomware", - "uuid": "f656c54f-d252-4441-af31-f88a9fcc6ee4", - "value": "Faizal" - }, - { - "description": "Ransomware", - "uuid": "27e5da0f-5f6c-460c-b1b7-03e78724ab07", - "value": "Fake Cerber" - }, - { - "description": "ransomware", - "uuid": "bc7a4be2-1997-40ba-beb7-553120b1411b", - "value": "Fake DMA" - }, - { - "description": "ransomware", - "uuid": "29cd31bb-819f-4d01-9805-ba9656a2d215", - "value": "FartPlz" - }, - { - "description": "ransomware", - "uuid": "6d97efca-8d12-45d3-93c3-93a4d3839110", - "value": "FBLocker" - }, - { - "description": "ransomware", - "uuid": "3a05c407-80bc-491d-9065-97b53137694c", - "value": "FCP" - }, - { - "description": "ransomware", - "uuid": "42aea797-8789-43ed-aca5-0c492a3a8970", - "value": "FCrypt" - }, - { - "description": "ransomware", - "uuid": "010a5c7b-ec43-4540-9c67-4b4f73c82c06", - "value": "FCT" - }, - { - "description": "ransomware", - "uuid": "4e344305-4a3b-43b5-a2a6-5cf669e416e7", - "value": "Fenrir" - }, - { - "description": "ransomware", - "uuid": "7c698732-90bb-4a72-a8ac-f6194761c546", - "value": "File Ripper" - }, - { - "description": "ransomware", - "uuid": "35c968af-cee9-40bf-9d62-b8ba5d6dbc8f", - "value": "FileFuck" - }, - { - "description": "ransomware", - "uuid": "39a197ff-be4b-45a7-bdc8-fc17af421d63", - "value": "FilesL0cker" - }, - { - "description": "ransomware", - "uuid": "06db1c0f-5dcd-4dad-8fb5-cdf8afdf2ab6", - "value": "Final" - }, - { - "description": "ransomware", - "uuid": "02c5bf92-23e8-404c-9fe9-5e50f587d0c4", - "value": "FindZip" - }, - { - "description": "ransomware", - "uuid": "b9f1d220-2ef0-4b1d-84ed-ae6843e5828e", - "value": "Flatcher3" - }, - { - "description": "ransomware", - "uuid": "51f42a21-1963-40c5-b644-d4c1c5c3f9eb", - "value": "Fluffy-TAR" - }, - { - "description": "ransomware", - "uuid": "10254366-b6d0-4266-a277-6ef4eee460b3", - "value": "Foxy" - }, - { - "description": "ransomware", - "uuid": "0b6e29d4-27e4-422b-944f-72e111462dee", - "value": "FreeMe" - }, - { - "description": "ransomware", - "uuid": "a5e54d82-cb41-420e-a03d-89b762560dcc", - "value": "Freshdesk" - }, - { - "description": "ransomware", - "uuid": "5df125ae-9362-415d-a915-f478447eece5", - "value": "Frog" - }, - { - "description": "ransomware", - "uuid": "61c215e0-835b-488a-8e82-94da05871b80", - "value": "FrozrLock" - }, - { - "description": "ransomware", - "uuid": "8467b6f2-7132-4695-87a6-6a7400c3a7d8", - "value": "FRS" - }, - { - "description": "ransomware", - "uuid": "d81208be-6715-4ef5-b354-9283d7eed531", - "value": "FScrypt" - }, - { - "description": "ransomware", - "uuid": "db9571dc-7ebc-4f2b-a31b-944851c16346", - "value": "FuckTheSystem" - }, - { - "description": "ransomware", - "uuid": "6247ab38-e6dd-4020-8771-f1fdfc9e86bd", - "value": "FuxSocy Encryptor" - }, - { - "description": "ransomware", - "uuid": "1ef5a7de-9fe2-4cfb-a6ff-7f63bc31bf94", - "value": "Galacti-Crypter" - }, - { - "description": "ransomware", - "uuid": "9734c2bc-d638-4b69-9189-c6141f66bcab", - "value": "GameOver" - }, - { - "description": "ransomware", - "uuid": "dd9dd6b6-97c6-4cd1-bd3a-f7e95526b090", - "value": "Geminis3" - }, - { - "description": "ransomware", - "uuid": "0a59664f-b447-4c5e-b8e4-8842e381390b", - "value": "Gendarmerie" - }, - { - "description": "ransomware", - "uuid": "317eee8b-2a8b-4d2a-a17c-9fa651de2f06", - "value": "Genobot" - }, - { - "description": "ransomware", - "uuid": "7f94ad48-3321-4fbb-850d-a0e6cb300815", - "value": "GermanWiper" - }, - { - "description": "ransomware", - "uuid": "857a6d87-3fe7-426a-8679-7029134800af", - "value": "GhosTEncryptor" - }, - { - "description": "ransomware", - "uuid": "66c1ee94-a302-4f25-a54a-fdc2e2c3d164", - "value": "GhostHammer" - }, - { - "description": "ransomware", - "uuid": "abf2485a-8fc6-46a5-9400-d188711a3cb2", - "value": "Gibberish" - }, - { - "description": "ransomware", - "uuid": "5845d539-8c80-4957-92ea-7aa968ec784c", - "value": "Gibon" - }, - { - "description": "ransomware", - "uuid": "f03fb4bc-7762-4529-bce1-d851619fb0d4", - "value": "Giyotin" - }, - { - "description": "ransomware", - "uuid": "c18fb798-f2f8-4119-aee3-5888241d129f", - "value": "GoCryptoLocker" - }, - { - "description": "ransomware", - "uuid": "287f5d11-c1da-4409-8404-543c68cc968e", - "value": "Godra" - }, - { - "description": "ransomware", - "uuid": "df998c50-52d0-462d-9bbb-5b93a5adc7b0", - "value": "GoGoogle" - }, - { - "description": "ransomware", - "uuid": "e88b85ed-d20d-416a-bde9-2a2ba60f9c70", - "value": "GoHack" - }, - { - "description": "ransomware", - "uuid": "c51e8939-8b5d-4b5e-a73e-92944e1392c0", - "value": "Golden Axe" - }, - { - "description": "ransomware", - "uuid": "61fbe157-557a-40c4-919f-d61f6f7b5f2f", - "value": "Gomme" - }, - { - "description": "ransomware", - "uuid": "269bae29-5955-4723-8f33-b81767f44c82", - "value": "GonnaCry Ransmware" - }, - { - "description": "ransomware", - "uuid": "9325868e-bc3a-43d7-ba18-cd5d372eea06", - "value": "Goofed HT" - }, - { - "description": "ransomware", - "uuid": "7b8f0dea-b63a-4b70-ae4b-2a06afd9d438", - "value": "GoRansom POC" - }, - { - "description": "ransomware", - "uuid": "99cf422f-785c-4459-86a0-15f4204f17d2", - "value": "Gorgon" - }, - { - "description": "ransomware", - "uuid": "a7c78489-4545-4d5f-a280-0b919ee23c3f", - "value": "Gotcha" - }, - { - "description": "ransomware", - "uuid": "c694aab7-1c1c-4a36-9fa1-da8860f75ab3", - "value": "GottaCry" - }, - { - "description": "ransomware", - "uuid": "11684b37-3bc6-4d74-b72e-8689f5340bc2", - "value": "GPAA" - }, - { - "description": "ransomware", - "uuid": "c479cd06-3935-4673-abc2-fb2a69b04c23", - "value": "GPGQwerty" - }, - { - "description": "ransomware", - "uuid": "ae7dcbb6-044a-427a-8392-7697c4e1bef7", - "value": "Craftul" - }, - { - "description": "ransomware", - "uuid": "9f7c8936-96ee-4f99-a61c-8c51b4c93c9d", - "value": "Greystars" - }, - { - "description": "ransomware", - "uuid": "e7c56607-ad06-4b6c-881d-5076e083d5d4", - "value": "GrodexCrypt" - }, - { - "description": "ransomware", - "uuid": "b7025c7b-e650-4e8e-83b8-1311bd684b65", - "value": "GrujaRSorium" - }, - { - "description": "ransomware", - "uuid": "d980b021-485e-4515-a629-11a42a67b36c", - "value": "Gruxer" - }, - { - "description": "ransomware", - "uuid": "b0d5f511-7542-46e5-b95a-53c2c56a2683", - "value": "GusCrypter" - }, - { - "description": "ransomware", - "uuid": "e9269244-a119-4c0a-92fd-a3b3617670d8", - "value": "GX40" - }, - { - "description": "ransomware", - "uuid": "9cfe0adf-72e8-44c8-bdce-4c2c2a7749bf", - "value": "H34rtBl33d" - }, - { - "description": "ransomware", - "uuid": "1d689032-cca4-4c40-86db-1eabd2a7cd29", - "value": "HackdoorCrypt3r" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "related": [ - { - "dest-uuid": "31945e7b-a734-4333-9ea2-e52051ca015a", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "c0091a62-b1cd-495d-898b-d2f3b5af601e", - "value": "Hades" - }, - { - "description": "ransomware", - "uuid": "49e5c755-510d-4eca-a45d-8561a53f6bfa", - "value": "Hakbit" - }, - { - "description": "ransomware", - "uuid": "a5c17b66-ee15-4a08-9eb6-348bb6adeb33", - "value": "HappyCrypter" - }, - { - "description": "ransomware", - "uuid": "8d551d9e-f14c-473e-a896-7cee4fc09e82", - "value": "Haze" - }, - { - "description": "ransomware", - "uuid": "e9863c6d-d081-4f8b-bffd-de2004f93897", - "value": "HCrypto" - }, - { - "description": "ransomware", - "uuid": "3347541a-772d-4b83-a7fd-b9a98569eb8e", - "value": "HELP@AUSI" - }, - { - "description": "ransomware", - "uuid": "526166b7-59a5-4946-9d50-d95788e4d28f", - "value": "HelpDCFile" - }, - { - "description": "ransomware", - "uuid": "5ad18348-acb0-430c-8439-ea2b7c6438e6", - "value": "HelpMe" - }, - { - "description": "ransomware", - "uuid": "718b274e-b547-42dc-ada4-b47e213cd625", - "value": "Hermes837" - }, - { - "description": "ransomware", - "uuid": "2b2379e5-098e-4c62-be82-79ee4e3cc61c", - "value": "HermesVirus HT" - }, - { - "description": "ransomware", - "uuid": "c7e0650f-efbe-4c2e-bef7-ff824fb5a152", - "value": "Heropoint" - }, - { - "description": "ransomware", - "uuid": "7c2a199e-1ed6-4820-a3e2-80c45ff6f709", - "value": "HiddenBeer" - }, - { - "description": "ransomware", - "uuid": "38b8fb07-8545-4f79-8094-fed524e263c4", - "value": "Honor" - }, - { - "description": "ransomware", - "uuid": "bdd46a71-888d-4091-b55e-2fb9ff11a770", - "value": "Horros" - }, - { - "description": "ransomware", - "uuid": "2e4f26d6-f220-4877-be0e-45059b0f8eeb", - "value": "Hydra" - }, - { - "description": "ransomware", - "uuid": "496e3fb8-666c-4dd0-a06f-af1358320f6e", - "value": "IGotYou" - }, - { - "description": "ransomware", - "uuid": "17e7cef2-74fb-4abc-9d83-a65a50654381", - "value": "iGZa4C" - }, - { - "description": "ransomware", - "uuid": "f7947cfd-dfac-437d-bc9d-3b71470d222a", - "value": "ILElection2020" - }, - { - "description": "ransomware", - "uuid": "03429647-cc47-49ee-b336-4fa866abf510", - "value": "Ims00ry" - }, - { - "description": "ransomware", - "uuid": "9c8eadbf-c1d0-4726-85ac-3d595efadf9d", - "value": "ImSorry" - }, - { - "description": "ransomware", - "uuid": "719a97ab-4324-433f-aee0-f42712feb00b", - "value": "Incanto" - }, - { - "description": "ransomware", - "uuid": "ddb76772-bfc9-4896-92ee-b7baf6f1a07e", - "value": "Indrik" - }, - { - "description": "ransomware", - "uuid": "de63a115-7a2b-4b0a-8898-8f3fa6768414", - "value": "InducVirus" - }, - { - "description": "ransomware", - "uuid": "40215dc5-5d28-4770-a85f-b6a71f1db5d9", - "value": "InfinityLock" - }, - { - "description": "ransomware", - "uuid": "5ec2d8cd-090d-4184-b865-53d71cbbc235", - "value": "InfoDot" - }, - { - "description": "ransomware", - "uuid": "6a4ac521-4731-4bc1-abf4-639b451018bc", - "value": "INPIVX" - }, - { - "description": "ransomware", - "uuid": "2a1ab564-52e1-4575-8184-20b68c1f23c6", - "value": "InsaneCrypt" - }, - { - "description": "ransomware", - "uuid": "82f52546-ed68-468d-96a1-d7064478d0de", - "value": "IPA" - }, - { - "description": "ransomware", - "uuid": "54c9604e-ba28-4fa7-9a39-125fe0fbf0cb", - "value": "IT.Books" - }, - { - "description": "ransomware", - "uuid": "159953eb-01f1-4325-9467-54a4c7bdeebb", - "value": "J-" - }, - { - "description": "ransomware", - "uuid": "7770c955-5d04-42c2-8421-3a38c7bebf90", - "value": "JabaCrypter" - }, - { - "description": "ransomware", - "uuid": "d712d488-e189-4fc1-82ce-ef6bb0ecad4e", - "value": "Jaffe" - }, - { - "description": "ransomware", - "uuid": "72e2f10d-9c6a-407d-9e7d-f76c1c8248f2", - "value": "James" - }, - { - "description": "ransomware", - "uuid": "5b8990a3-0e8c-4b81-8d3c-cc8e6b5024eb", - "value": "Java NotDharma" - }, - { - "description": "ransomware", - "uuid": "f1486237-a5da-48aa-8681-45b389ef2fa2", - "value": "jCandy" - }, - { - "description": "ransomware", - "uuid": "d2f5c189-5707-4bec-88d9-0d0bd864cfae", - "value": "JeepersCrypt" - }, - { - "description": "ransomware", - "uuid": "cd334e6e-893b-4dc1-beeb-484f542d0d50", - "value": "Jemd" - }, - { - "description": "ransomware", - "uuid": "07b4eda8-d346-4218-8c4d-a553ae4f684a", - "value": "JesusCrypt" - }, - { - "description": "ransomware", - "uuid": "93b502df-b300-4ea6-af49-85901d9bfc6d", - "value": "JNEC.a" - }, - { - "description": "ransomware", - "uuid": "4bbe43a3-ca75-4f93-973b-2179770ad606", - "value": "JoeGo" - }, - { - "description": "ransomware", - "uuid": "2e8763e0-5584-4f9a-ac60-d111a30a887c", - "value": "Jolly Roger" - }, - { - "description": "ransomware", - "uuid": "2e63db1d-5ce9-4cb4-a75a-86afd2d450ec", - "value": "JosepCrypt" - }, - { - "description": "ransomware", - "uuid": "41ae4021-d6a6-4f19-9414-ff4d78ae2f21", - "value": "Juwon" - }, - { - "description": "ransomware", - "uuid": "b484ef6b-ac11-4fe2-a87c-5731c280b4aa", - "value": "Kali" - }, - { - "description": "ransomware", - "uuid": "6352d423-003a-4545-91d6-bb66425a3edd", - "value": "Kamil" - }, - { - "description": "ransomware", - "uuid": "8f8e32fe-05a1-4125-a287-27ff372b9f56", - "value": "Kampret" - }, - { - "description": "ransomware", - "uuid": "e04a4847-38df-4f14-8b16-6b6da7d5e222", - "value": "Karo" - }, - { - "description": "ransomware", - "uuid": "739c4582-7471-43f3-aa21-3c181fe6713c", - "value": "Katafrank" - }, - { - "description": "ransomware", - "uuid": "3744333c-49b7-45cb-9059-6933725fa725", - "value": "Katyusha" - }, - { - "description": "ransomware", - "uuid": "b17ec2bc-bcc7-4f75-9338-ee7ec64a7a49", - "value": "KCTF Locker" - }, - { - "description": "ransomware", - "uuid": "47e97378-20da-40d4-b6bc-99dd2aba84d2", - "value": "KCW" - }, - { - "description": "ransomware", - "uuid": "a307a755-a243-4b00-b1ef-11b08049ca29", - "value": "Kee" - }, - { - "description": "ransomware", - "uuid": "ccb50fe4-dbcf-4773-933b-0cd27b08e81b", - "value": "KEKW" - }, - { - "description": "ransomware", - "uuid": "389ad313-aceb-4ee1-8554-8aec78a2f7b6", - "value": "Kerkoporta" - }, - { - "description": "ransomware", - "uuid": "55cebdaf-adfb-4943-b169-4652af84e0da", - "value": "KeyMaker" - }, - { - "description": "ransomware", - "uuid": "fc59e09e-49a2-4751-a3c8-0def51fbbd61", - "value": "KillBot_Virus" - }, - { - "description": "ransomware", - "uuid": "d6d91cbd-4ad9-4cf4-b5fa-a468da62b421", - "value": "KillDisk-Dimens" - }, - { - "description": "ransomware", - "uuid": "01dc9bbb-b888-4aa5-b6a2-d216eaa95f84", - "value": "KillRabbit" - }, - { - "description": "ransomware", - "uuid": "f4d370e2-7d91-4bd0-9b1f-33160d4b989f", - "value": "KillSwitch" - }, - { - "description": "ransomware", - "uuid": "74a66fc7-bd18-4f43-a9c1-c22cfe98d101", - "value": "Kindest" - }, - { - "description": "ransomware", - "uuid": "7a502648-9097-41ae-a686-8f9365923daa", - "value": "KKK" - }, - { - "description": "ransomware", - "uuid": "c099771d-82dd-45b6-9a1b-e5590eac897a", - "value": "Kovter" - }, - { - "description": "ransomware", - "uuid": "6ba8bc69-bd70-4672-a167-123bfb260ecb", - "value": "Kriptovor" - }, - { - "description": "ransomware", - "uuid": "d93b5179-d747-4845-b4cd-61b9566aa823", - "value": "Krypte" - }, - { - "description": "ransomware", - "uuid": "822b3254-d715-46bc-8011-c5b647d314dc", - "value": "Krypton" - }, - { - "description": "ransomware", - "uuid": "377a0893-a5f0-4b78-a410-ef814083ae27", - "value": "Kryptonite RBY" - }, - { - "description": "ransomware", - "uuid": "4a3ce744-3468-4ddf-95f9-7095bdd0d65e", - "value": "Kryptonite Snake" - }, - { - "description": "ransomware", - "uuid": "de0bf4df-c578-41f1-b7db-20a1ae481844", - "value": "Kupidon" - }, - { - "description": "ransomware", - "uuid": "a613ff2c-d23c-468b-b53f-c140be5d6457", - "value": "Ladon" - }, - { - "description": "ransomware", - "uuid": "a4a865b8-9b7c-4ec4-b448-ad8b1524f928", - "value": "Lalabitch_ransomware" - }, - { - "description": "ransomware", - "uuid": "a026f575-384f-4a5a-b76d-7baa223661b2", - "value": "LazagneCrypt" - }, - { - "description": "ransomware", - "uuid": "a7c9904b-758f-4107-bffb-12d190e08687", - "value": "Light" - }, - { - "description": "ransomware", - "uuid": "cfbc0527-0301-49f5-a38b-d9d2d73c4256", - "value": "LightningCrypt" - }, - { - "description": "ransomware", - "uuid": "2d3d3c5e-fc6b-4afb-a81b-9b0de8e78446", - "value": "LIGMA" - }, - { - "description": "ransomware", - "uuid": "dd518ffc-8f62-44f0-9eba-b565137ee4c2", - "value": "Lime" - }, - { - "description": "ransomware", - "uuid": "c96c1d9c-9f7d-47ac-9849-6a9e4c049f55", - "value": "Litra" - }, - { - "description": "ransomware", - "uuid": "0ea3f9fd-9f2a-4491-9492-e655344fd5ec", - "value": "LittleFinger" - }, - { - "description": "ransomware", - "uuid": "f3dfd38d-9795-4c2f-92f8-683f252c7935", - "value": "LMAOxUS" - }, - { - "description": "ransomware", - "uuid": "eed8bf9a-cbb6-4096-9511-7a3cf47d10c4", - "value": "LockBox" - }, - { - "description": "ransomware", - "uuid": "07b6bb3b-e738-466e-9267-78587c3dea6b", - "value": "Locked_File" - }, - { - "description": "ransomware", - "uuid": "3a29a37a-528a-4fd5-b6c8-a5be64c88c15", - "value": "LockedByte" - }, - { - "description": "ransomware", - "uuid": "d62a826b-9d74-4e04-8e12-9cb918c0ee80", - "value": "Locker-Pay" - }, - { - "description": "ransomware", - "uuid": "8622375e-47c3-4542-be21-cc76969cdaa1", - "value": "Lockify" - }, - { - "description": "ransomware", - "uuid": "c493f2e3-7fdc-41f5-8450-1e01dd92c339", - "value": "LockMe" - }, - { - "description": "ransomware", - "uuid": "229959ff-de0f-46d5-9ded-5026944adc13", - "value": "LockOn" - }, - { - "description": "ransomware", - "uuid": "70fa1062-fdb1-424b-b29e-c4497c4f9df4", - "value": "Lockout" - }, - { - "description": "ransomware", - "uuid": "23ccf1d7-4f68-4c95-a8a4-eeff5720be63", - "value": "LongTermMemoryLoss" - }, - { - "description": "ransomware", - "uuid": "1609a28b-9da4-419f-8df9-0589d842f231", - "value": "LonleyCrypt" - }, - { - "description": "ransomware", - "uuid": "706d91b7-990b-486f-bf6b-33ffdc704039", - "value": "LooCipher" - }, - { - "description": "ransomware", - "uuid": "de60a270-8ed2-4b39-b90c-ebbd7821962d", - "value": "LordOfShadow" - }, - { - "description": "ransomware", - "uuid": "98c9333d-9c94-436d-9f37-3ba4354cad32", - "value": "Losers" - }, - { - "description": "ransomware", - "uuid": "29a65541-4638-4acc-9627-f5cfd5d719d0", - "value": "Losers-Dangerous" - }, - { - "description": "ransomware", - "uuid": "2c5d28fa-1ca9-45ff-9ea6-943a1fd375af", - "value": "Lost_Files" - }, - { - "description": "ransomware", - "uuid": "92312287-ab2b-4246-a46b-c9b41714571b", - "value": "LuckyJoe" - }, - { - "description": "ransomware", - "uuid": "0e372055-134e-4360-b62e-ad65ee20a2c4", - "value": "Luxnut" - }, - { - "description": "ransomware", - "uuid": "d44c76ea-ab96-4f95-aa51-471c779de3d1", - "value": "Madafakah" - }, - { - "description": "ransomware", - "uuid": "27e23341-bbcd-4eae-992e-f0a0c87e3b40", - "value": "MadBit" - }, - { - "description": "ransomware", - "uuid": "7fe890f7-db7f-4cef-ad9f-9e44d445ef8a", - "value": "Magician" - }, - { - "description": "ransomware", - "uuid": "8ee63c4b-eb0d-47f1-b867-41afb64a5686", - "value": "Malabu" - }, - { - "description": "ransomware", - "uuid": "bd2800dc-62b8-4e77-bde5-1a1b0c4d2502", - "value": "MalwareTech's CTF" - }, - { - "description": "ransomware", - "uuid": "c430f580-6ba9-44fa-a8c5-9ccfff339940", - "value": "Mancros+AI4939" - }, - { - "description": "ransomware", - "uuid": "e1b124d6-6a92-4d0a-a116-ae8f448e5dc3", - "value": "Maoloa" - }, - { - "description": "ransomware", - "uuid": "cf316be5-f76f-4c9a-8cc1-52214bb18896", - "value": "Marozka" - }, - { - "description": "ransomware", - "uuid": "3121238f-0982-4a10-92fc-047fbd658784", - "value": "MarraCrypt" - }, - { - "description": "ransomware", - "uuid": "20f3f441-7285-4b83-a2a1-fad2d23b1048", - "value": "Matroska" - }, - { - "description": "ransomware", - "uuid": "9b9f3cc7-7cb8-4431-8187-d7494703d618", - "value": "MauriGo" - }, - { - "description": "ransomware", - "uuid": "b219c747-81da-45c5-88a6-50a1a4642ba0", - "value": "MaxiCrypt" - }, - { - "description": "ransomware", - "uuid": "d5c3b64f-c9b4-4f48-9391-6f0d5ac8f5e4", - "value": "Maykolin" - }, - { - "description": "ransomware", - "uuid": "82b3dd0f-eb99-4866-aaa2-af4f4182d612", - "value": "Maysomware" - }, - { - "description": "ransomware", - "uuid": "2a803db3-8962-4d2f-8397-e3301b57cef7", - "value": "MBR-ONI" - }, - { - "description": "ransomware", - "uuid": "627d603a-906f-4fbf-b922-f03eea4578fe", - "value": "MedusaLocker" - }, - { - "description": "ransomware", - "uuid": "6a985c3b-8ad9-4005-b363-854f6f6f4dcd", - "value": "Meduza" - }, - { - "description": "ransomware", - "uuid": "60ec39c9-25d2-4d04-ad2e-4f9293159e84", - "value": "MegaLocker" - }, - { - "description": "ransomware", - "uuid": "1d274b68-a9c9-4418-a430-df9e4f0d4f4a", - "value": "Mew767" - }, - { - "description": "ransomware", - "uuid": "08e17d21-6f58-4eef-aee5-0dd842ca6eee", - "value": "Mike NotSTOP" - }, - { - "description": "ransomware", - "uuid": "dce3f8d4-9381-4b91-8cf5-e33e55a1e199", - "value": "Mikoyan" - }, - { - "description": "ransomware", - "uuid": "ae96d561-5f2e-43ce-9b82-7a81e825758a", - "value": "MindLost" - }, - { - "description": "ransomware", - "uuid": "8051a21d-8967-4674-a6c3-dc794df43fe0", - "value": "MindSystem" - }, - { - "description": "ransomware", - "uuid": "804c576e-8679-47ff-9550-0c1abe896e46", - "value": "Mini" - }, - { - "description": "ransomware", - "uuid": "63f2149a-c736-4a7d-86f9-0993cb568630", - "value": "Minotaur" - }, - { - "description": "ransomware", - "uuid": "6c01d999-123f-4301-939d-a65bbcf00d90", - "value": "MMM" - }, - { - "description": "ransomware", - "uuid": "c4461bdf-560d-4f89-a5cb-f0960a720687", - "value": "MNS CryptoLocker" - }, - { - "description": "ransomware", - "uuid": "98c9ebce-d11c-41b7-9923-4e94dca22fb0", - "value": "MoneroPay" - }, - { - "description": "ransomware", - "uuid": "4f579928-8f50-459c-8878-df1c75437c38", - "value": "MongoLock" - }, - { - "description": "ransomware", - "uuid": "8e103d80-1e53-42b0-a21a-5a2bcefa7d3f", - "value": "MoonCryptor" - }, - { - "description": "ransomware", - "uuid": "b14d39e1-36ea-45a9-8609-95ac7ffce3cd", - "value": "Mordor" - }, - { - "description": "ransomware", - "uuid": "21181132-affd-464e-81cd-35ef575fc56d", - "value": "MorrisBatchCrypt" - }, - { - "description": "ransomware", - "uuid": "eecce3be-ba24-4cf4-b9cf-8780533dc487", - "value": "Moth" - }, - { - "description": "ransomware", - "uuid": "a319539b-ccd0-4278-83fa-9419331bb1f2", - "value": "MoWare H.F.D" - }, - { - "description": "ransomware", - "uuid": "c21111d1-fc51-437a-9c73-1b89922bea95", - "value": "Mr.Locker" - }, - { - "description": "ransomware", - "uuid": "7221c504-c3a3-4020-9490-01e569aeddcb", - "value": "Mr403Forbidden" - }, - { - "description": "ransomware", - "uuid": "754ea5a6-6d56-482c-bb0a-c6618fca4390", - "value": "MuchLove" - }, - { - "description": "ransomware", - "uuid": "7f8d5860-35db-4f23-a174-514a0066e573", - "value": "Muhstik" - }, - { - "description": "ransomware", - "uuid": "0a68c300-6ce0-4664-9956-3abafb3e526e", - "value": "Mystic" - }, - { - "description": "ransomware", - "uuid": "6aa66f32-54f7-46b7-bb5b-9e953bf97ced", - "value": "MZP" - }, - { - "description": "ransomware", - "uuid": "eeb3c94c-1424-49a9-831b-36bbd9e81a1d", - "value": "N2019cov" - }, - { - "description": "ransomware", - "uuid": "c06b039c-7a68-4f35-9948-87934f287ddd", - "value": "Naampa" - }, - { - "description": "ransomware", - "uuid": "2fe2b576-9673-46b2-b558-811c26db3f6b", - "value": "NazCrypt" - }, - { - "description": "ransomware", - "uuid": "d12f369c-f776-468a-8abf-8000b1b30642", - "value": "Nefilim" - }, - { - "description": "ransomware", - "uuid": "38fbf2d7-10a2-4cb2-9d50-cb2434a55c10", - "value": "Negozl" - }, - { - "description": "ransomware", - "uuid": "686d157c-6c30-4ffb-b192-ca99d90770da", - "value": "Neitrino" - }, - { - "description": "ransomware", - "uuid": "78c192ac-7fb6-4c85-8e20-9f86f4633873", - "value": "NewWave" - }, - { - "description": "ransomware", - "uuid": "d6899ce2-7d67-4730-9a32-4721051d33f9", - "value": "NextCry" - }, - { - "description": "ransomware", - "uuid": "e361e083-de14-4ffd-80b9-f071096ab973", - "value": "Nightmare" - }, - { - "description": "ransomware", - "uuid": "d79ab668-4720-4875-8959-436c7fd81022", - "value": "NinjaLoc" - }, - { - "description": "ransomware", - "uuid": "ab9ece36-6218-4467-929f-d07192a98b6a", - "value": "NM4" - }, - { - "description": "ransomware", - "uuid": "fd447eea-9e79-4143-8e7d-246b022c7950", - "value": "Noblis" - }, - { - "description": "ransomware", - "uuid": "6db73f66-912d-43f7-ae21-7988aed2ea22", - "value": "Nog4yH4n" - }, - { - "description": "ransomware", - "uuid": "2a0b033f-c14c-42ec-9f10-57dc2de3639e", - "value": "Nomikon" - }, - { - "description": "ransomware", - "uuid": "bf54e9f3-81af-43f7-b378-0109c4adc489", - "value": "NotAHero" - }, - { - "description": "ransomware", - "uuid": "6fc911ca-2f9c-428e-8986-aff706edee92", - "value": "Nozelesn" - }, - { - "description": "ransomware", - "uuid": "619ccdda-2f40-48fe-9492-dd12c70a4029", - "value": "Nulltica" - }, - { - "description": "ransomware", - "uuid": "8f869515-4c4e-4cd0-8b15-9dc3f9a43902", - "value": "Nx / OSR" - }, - { - "description": "ransomware", - "uuid": "e8bc21bf-ddfa-4245-89b4-19cfb430eb7d", - "value": "Nyton" - }, - { - "description": "ransomware", - "uuid": "641b511e-c974-4584-b8ab-08c1296ac73b", - "value": "NZMR" - }, - { - "description": "ransomware", - "uuid": "9686665e-b862-4399-84b9-407714df1677", - "value": "Ogre" - }, - { - "description": "ransomware", - "uuid": "c1470d12-fd35-497e-b1cf-0484e755b7a2", - "value": "OhNo!" - }, - { - "description": "ransomware", - "uuid": "652d3fdd-a641-4553-8695-69e0ef74bd1c", - "value": "Oled" - }, - { - "description": "ransomware", - "uuid": "9162c2e1-6936-4c13-a8c3-c10eab321bd5", - "value": "OmniSphere" - }, - { - "description": "ransomware", - "uuid": "47273227-8079-46e6-9b89-3abdd39c017f", - "value": "One" - }, - { - "description": "ransomware", - "uuid": "3358ae46-afcd-4685-81b6-75970f502660", - "value": "ONI" - }, - { - "description": "ransomware", - "uuid": "d056b6f3-4cb0-41a8-a0f5-4fec33871697", - "value": "OoPS Ramenware" - }, - { - "description": "ransomware", - "uuid": "3c2ce8a5-e060-4466-847a-3c2db9282bd6", - "value": "OopsLocker" - }, - { - "description": "ransomware", - "uuid": "88b486e5-ccb2-4f67-8967-f841fb28ea76", - "value": "OPdailyallowance" - }, - { - "description": "ransomware", - "uuid": "1e63a74c-a975-4997-ae2c-4ac9196412e4", - "value": "OpenToYou" - }, - { - "description": "ransomware", - "uuid": "c1a4ddf5-cfe6-4482-a8d4-69761eff0554", - "value": "Ordinal" - }, - { - "description": "ransomware", - "uuid": "c624a4b1-b4aa-4810-b860-45545c6ecb50", - "value": "Ordinypt" - }, - { - "description": "ransomware", - "uuid": "0ef81fda-237e-4d28-8bd7-f05c748eb0d8", - "value": "Pacman" - }, - { - "description": "ransomware", - "uuid": "4857ec1b-7d5f-487d-a2cd-91588158fe49", - "value": "PassLock" - }, - { - "description": "ransomware", - "uuid": "8acc6960-3eb9-479d-a745-7c7eddacc0f2", - "value": "Pay-or-Lost" - }, - { - "description": "ransomware", - "uuid": "dc5be315-4829-448a-9359-05d5b9187756", - "value": "PayForNature" - }, - { - "description": "ransomware", - "uuid": "ef63051e-a99e-43db-b81d-80ec95e74610", - "value": "Paymen45" - }, - { - "description": "ransomware", - "uuid": "7a2eeb1a-6ae3-4e1c-a4f7-af4a0be2d98e", - "value": "Payment" - }, - { - "description": "ransomware", - "uuid": "2a20dd7e-242e-45ac-8245-1864320ed157", - "value": "PClock и PClock2" - }, - { - "description": "ransomware", - "uuid": "fc91d065-21c2-44ae-9169-241d60f1a786", - "value": "PPDDDP" - }, - { - "description": "ransomware", - "uuid": "0df4ba53-b7c9-4e2a-979d-f8e3d7737aa9", - "value": "PEC 2017" - }, - { - "description": "ransomware", - "uuid": "05f9a3ce-2611-40b9-b788-c8dc7233e5a7", - "value": "Pendor" - }, - { - "description": "ransomware", - "uuid": "48bef862-8a8c-4eeb-b72c-a756762b52c7", - "value": "Pennywise" - }, - { - "description": "ransomware", - "uuid": "512d011c-81a8-4218-866c-1497f4572caf", - "value": "PewCrypt +decrypt" - }, - { - "description": "ransomware", - "uuid": "c37cf393-f299-4b02-864c-5e7e5f244d04", - "value": "PewDiePie" - }, - { - "description": "ransomware", - "uuid": "bbbfe905-6236-419a-ab21-a33202597b1c", - "value": "PhobosImposter" - }, - { - "description": "ransomware", - "uuid": "37a26943-99b6-40ae-984d-91e044546d1b", - "value": "PhoneNumber" - }, - { - "description": "ransomware", - "uuid": "70ce8986-d1c3-4e10-8096-1ee2539f11d7", - "value": "PHP" - }, - { - "description": "ransomware", - "uuid": "5822a3dc-64b3-4303-b0ba-d2e804a5015c", - "value": "Pirateware" - }, - { - "description": "ransomware", - "uuid": "88c32b3b-daa1-4cec-8e05-753ee5785704", - "value": "PoisonFang" - }, - { - "description": "ransomware", - "uuid": "fc3984d8-b1c6-45e7-8d36-e51532c9b7fc", - "value": "PonyFinal" - }, - { - "description": "ransomware", - "uuid": "bd401c00-e690-4dae-80ac-c47aab227e5f", - "value": "PooleZoor" - }, - { - "description": "ransomware", - "uuid": "d494a2e6-17e6-435f-9bcd-ef728d18f504", - "value": "PopCornTime" - }, - { - "description": "ransomware", - "uuid": "3687c99c-f44e-421d-a04d-0a80d086c53a", - "value": "PowerHentai" - }, - { - "description": "ransomware", - "uuid": "662bf791-0a13-48e8-9f21-07dfb328d02b", - "value": "PowerLocky" - }, - { - "description": "ransomware", - "uuid": "5ed83975-a681-4061-8314-9ef76f319ef2", - "value": "PowerShell Locker 2013" - }, - { - "description": "ransomware", - "uuid": "b9a6faf4-733d-44b3-889b-ec468697ba3f", - "value": "PowerShell Locker 2015" - }, - { - "description": "ransomware", - "uuid": "535916a2-283b-4512-bc8b-e5d98c055fab", - "value": "Pr0tector" - }, - { - "description": "ransomware", - "uuid": "d8da450f-5e17-4301-b1ba-5468aa69d17a", - "value": "Predator" - }, - { - "description": "ransomware", - "uuid": "bd351d3d-3633-4aba-a35e-82cb7a00b2d5", - "value": "Priapos" - }, - { - "description": "ransomware", - "uuid": "114fbac2-6d2b-46b5-bc08-ed0c94cd756e", - "value": "Project23" - }, - { - "description": "ransomware", - "uuid": "084f9aec-4ebc-46a2-be97-0d1d172be044", - "value": "Project57" - }, - { - "description": "ransomware", - "uuid": "c4417bfb-717f-48d9-bd56-bc9e85d07c19", - "value": "ProLock" - }, - { - "description": "ransomware", - "uuid": "f5390f29-d832-434d-8547-5cab7f82a93b", - "value": "Prometey" - }, - { - "description": "ransomware", - "uuid": "a732a730-3fb4-4642-a4c5-25edaf0a1b9f", - "value": "Protected" - }, - { - "description": "ransomware", - "uuid": "4274477b-65c7-4497-846b-c8beebc264a2", - "value": "PSCrypt" - }, - { - "description": "ransomware", - "uuid": "801d7e9f-8076-4d6f-894e-c557f3b9cfeb", - "value": "PshCrypt" - }, - { - "description": "ransomware", - "uuid": "7cce4912-900f-4d16-b2c5-37b9078f3d7b", - "value": "PTP" - }, - { - "description": "ransomware", - "uuid": "64c5896a-141c-41fb-bc58-705f008c7b8f", - "value": "Pulpy" - }, - { - "description": "ransomware", - "uuid": "119b0b4d-034e-4e58-a7a4-833f083848cd", - "value": "PureLocker" - }, - { - "description": "ransomware", - "uuid": "a8b6433c-fc01-4c77-9a89-5f0f57136aaa", - "value": "PwndLocker" - }, - { - "description": "ransomware", - "uuid": "bf927535-eaf2-48e4-9b38-287de9ec4a0b", - "value": "PyteHole" - }, - { - "description": "ransomware", - "uuid": "ee55d30a-8735-42f4-b8e9-3610959be772", - "value": "Python" - }, - { - "description": "ransomware", - "uuid": "b79b60a4-2b47-4bb1-b36e-602a03afc7cd", - "value": "PZDC" - }, - { - "description": "ransomware", - "uuid": "89cc64e1-d33c-4922-84d4-0467bdeddba6", - "value": "Qinynore" - }, - { - "description": "ransomware", - "uuid": "8f5b9eff-242d-4f9b-9aa6-c24f92f7f0f9", - "value": "QNAPCrypt" - }, - { - "description": "ransomware", - "uuid": "9bd4c0c6-e8fe-495a-99b8-b5ea741ff8ae", - "value": "QP" - }, - { - "description": "ransomware", - "uuid": "380c73bf-7734-44c4-9f46-063cbd20475f", - "value": "QuakeWay" - }, - { - "description": "ransomware", - "uuid": "60f4c416-8752-4d59-8e9e-b12f16afda83", - "value": "Qweuirtksd" - }, - { - "description": "ransomware", - "uuid": "2943ea4b-42e8-4e5c-9abb-d6c3e94b84ce", - "value": "R3store" - }, - { - "description": "ransomware", - "uuid": "8b1f7d30-1115-4ad2-a986-fd797edf2b4d", - "value": "RabbitFox" - }, - { - "description": "ransomware", - "uuid": "c07fd277-f133-4deb-84ef-2f651aa0d989", - "value": "Ramsey" - }, - { - "description": "ransomware", - "uuid": "93e70c60-6bd2-4f01-a28a-1ae287349d61", - "value": "RandomLocker" - }, - { - "description": "ransomware", - "uuid": "d2b23d28-c12d-422f-8558-0d79ed98d335", - "value": "RanRans" - }, - { - "description": "ransomware", - "uuid": "d2d0d87f-249f-4223-82b2-71c82df6c7f2", - "value": "Rans0mLocked" - }, - { - "description": "ransomware", - "uuid": "0c1b4371-9c6e-41f2-9410-e76a1094d0ca", - "value": "Ransed" - }, - { - "description": "ransomware", - "uuid": "dfdc4876-bc48-4748-822a-dcce1c4058c4", - "value": "Ransom102" - }, - { - "description": "ransomware", - "uuid": "493847f8-57b1-42cc-9303-6b1eb9576580", - "value": "RansomAES" - }, - { - "description": "ransomware", - "uuid": "b63ed281-5357-4d20-afef-3377b70fd48b", - "value": "RansomCuck" - }, - { - "description": "ransomware", - "uuid": "65844c85-ad66-46e9-bb44-f99e601179a2", - "value": "RansomMine" - }, - { - "description": "ransomware", - "uuid": "1f5c7ad1-5ec5-4e0f-b7e0-c87232693a5d", - "value": "Ransomnix" - }, - { - "description": "ransomware", - "uuid": "1fe7d70f-8540-4f21-8675-2fe72bacce85", - "value": "Ransom Prank" - }, - { - "description": "ransomware", - "uuid": "7ec4a72d-12d3-46bb-a796-0296db298935", - "value": "RansomUserLocker" - }, - { - "description": "ransomware", - "uuid": "8af10e62-84e7-45c5-ae10-db1106cec43a", - "value": "RansomWarrior" - }, - { - "description": "ransomware", - "uuid": "9fd0b741-44fb-42fe-bf3d-b36b807878fe", - "value": "Rapid" - }, - { - "description": "ransomware", - "uuid": "8a7c32fd-9851-40c3-9fd9-a889a015db5e", - "value": "Rapid 2.0" - }, - { - "description": "ransomware", - "uuid": "07ef8e30-7bcd-4f14-af50-a113fdf60774", - "value": "Rapid 3.0" - }, - { - "description": "ransomware", - "uuid": "84160999-eebb-4f76-8253-9e09d447f472", - "value": "Rapid-Gillette" - }, - { - "description": "ransomware", - "uuid": "8cd93feb-4bf0-4d97-b5a2-061198652f1a", - "value": "Ra" - }, - { - "description": "ransomware", - "uuid": "a9d76a58-0ab3-4942-b364-27f89a1915eb", - "value": "RaRuCrypt" - }, - { - "description": "ransomware", - "uuid": "81e4038a-5e4d-4df1-90b7-c4aef735d757", - "value": "RedBoot" - }, - { - "description": "ransomware", - "uuid": "c26438bb-5aa3-4de4-a749-329d2560a350", - "value": "Redkeeper" - }, - { - "description": "ransomware", - "uuid": "4b2746c5-77f3-4f46-90de-4a0816dcd621", - "value": "RedFox" - }, - { - "description": "ransomware", - "uuid": "56351998-4871-4b7c-9c4c-201aa2ef7eaa", - "value": "RedRum" - }, - { - "description": "ransomware", - "uuid": "7c23a477-ea87-48d9-8c7e-d9333c28e984", - "value": "Redshot" - }, - { - "description": "ransomware", - "uuid": "570ba51b-3ce7-4f5b-88a9-98b9f22f8397", - "value": "Reetner" - }, - { - "description": "ransomware", - "uuid": "ca306262-b8e9-46a1-abcd-db5df38b47d5", - "value": "RekenSom" - }, - { - "description": "ransomware", - "uuid": "f5d20d2c-2624-4a0a-a136-36457d65360b", - "value": "Relock" - }, - { - "description": "ransomware", - "uuid": "a27e94d4-9fcb-4729-926c-b507cad09674", - "value": "RensenWare" - }, - { - "description": "ransomware", - "uuid": "53386169-9045-4636-b4e9-fd9405663d71", - "value": "Rentyr" - }, - { - "description": "ransomware", - "uuid": "11367b8d-0627-4774-894a-032fde021979", - "value": "RestoLocker" - }, - { - "description": "ransomware", - "uuid": "f881e6a3-2298-4e82-9d0a-75ceddf0e822", - "value": "Resurrection" - }, - { - "description": "ransomware", - "uuid": "19274b88-c0dc-4e91-957b-93d4a992329b", - "value": "Retis" - }, - { - "description": "ransomware", - "uuid": "af2011f8-b076-43cf-afb7-a348a7b00b9a", - "value": "RetMyData" - }, - { - "description": "ransomware", - "uuid": "7f750865-50aa-40cb-9614-d7d1c357999b", - "value": "Revolution" - }, - { - "description": "ransomware", - "uuid": "8cf3f181-c136-4f09-82ea-f8c5e6ca4b64", - "value": "Reyptson" - }, - { - "description": "ransomware", - "uuid": "39e600c4-2c5b-4798-8a0e-0fa530c2bd0a", - "value": "Rhino" - }, - { - "description": "ransomware", - "uuid": "8c18e32f-0b02-4551-b53b-2ac25baaccaa", - "value": "Rijndael" - }, - { - "description": "ransomware", - "uuid": "34bdd9f9-94e6-4805-b6b5-27632686070f", - "value": "Rogue HT" - }, - { - "description": "ransomware", - "uuid": "64c573b7-80d1-42d0-9fac-dab07f5df00f", - "value": "Rontok" - }, - { - "description": "ransomware", - "uuid": "0283d153-30f5-4be0-9ab7-8eee91fccd63", - "value": "Rozlok" - }, - { - "description": "ransomware", - "uuid": "84a5bfc2-44dc-4ddf-95d7-387ff16c7415", - "value": "RSA-NI" - }, - { - "description": "ransomware", - "uuid": "ce28af26-b03e-45ca-8e6d-20fbb36233db", - "value": "RSA2048Pro" - }, - { - "description": "ransomware", - "uuid": "224966b2-8d6a-4602-8d7d-67e7c8b2068f", - "value": "Ruby" - }, - { - "description": "ransomware", - "uuid": "b48f7bab-c2ba-4f80-9547-4f2bfef38959", - "value": "Rush" - }, - { - "description": "ransomware", - "uuid": "15d0121a-aac9-41cb-a140-69c3eb739d4a", - "value": "Russenger" - }, - { - "description": "ransomware", - "uuid": "100741e9-1803-4be7-98a8-6e5eeb01a50d", - "value": "Russian EDA2" - }, - { - "description": "ransomware", - "uuid": "6c7c182b-2a7a-43be-91d8-2bc34d9273c1", - "value": "SAD" - }, - { - "description": "ransomware", - "uuid": "fb94c242-0b03-4338-8c5a-7e4357e5a69c", - "value": "SadComputer" - }, - { - "description": "ransomware", - "uuid": "a5aa9c7d-10f7-4091-9c9a-e02acdbe5ca6", - "value": "Sadogo" - }, - { - "description": "ransomware", - "uuid": "dd020ef8-0f84-4403-8e2a-09728582467f", - "value": "Salsa" - }, - { - "description": "ransomware", - "uuid": "2869ae30-4106-4080-a63b-be29caecf5b7", - "value": "Santa Encryptor" - }, - { - "description": "ransomware", - "uuid": "3f8ec946-b80d-45b6-ae82-bffbb0bb05d7", - "value": "Saramat" - }, - { - "description": "ransomware", - "uuid": "43690415-9a4f-4019-a02e-26ec3dd2961c", - "value": "SARansom" - }, - { - "description": "ransomware", - "uuid": "120b33e8-75e2-45bd-b7ba-6726ed2a4ad7", - "value": "Satan Cryptor 2.0" - }, - { - "description": "ransomware", - "uuid": "aefd8f3f-20c2-4b08-bd00-99c1e67152c4", - "value": "Satan's Doom Crypter" - }, - { - "description": "ransomware", - "uuid": "d7a08ff9-af25-45e5-9fb7-c54defd6f62c", - "value": "SatanCryptor Go" - }, - { - "description": "ransomware", - "uuid": "90db5ee9-f2de-47aa-a923-2862800b473b", - "value": "Saturn" - }, - { - "description": "ransomware", - "uuid": "3f2ed9f6-384b-4846-97d0-8dec61b9f03a", - "value": "Satyr" - }, - { - "description": "ransomware", - "uuid": "4790fcdd-deab-4a9d-a8b6-dc413dee4ff8", - "value": "SaveTheQueen" - }, - { - "description": "ransomware", - "uuid": "f9884cee-1105-4f39-9e42-dda43841fd56", - "value": "ScammerLocker HT" - }, - { - "description": "ransomware", - "uuid": "9d1e1894-28d6-412b-8014-ac6c92657bc9", - "value": "ScammerLocker Ph" - }, - { - "description": "ransomware", - "uuid": "eaea10da-947e-42f9-99c9-6a576fda3bdc", - "value": "Schwerer" - }, - { - "description": "ransomware", - "uuid": "4b6bea32-12bd-4ede-8912-f9037be3b454", - "value": "ScorpionLocker" - }, - { - "description": "ransomware", - "uuid": "23a6b580-6df0-4193-a66f-721bacbe60fc", - "value": "Scrabber" - }, - { - "description": "ransomware", - "uuid": "f13796ff-a16c-4cd0-b4e1-9f4593c90d2e", - "value": "Scroboscope" - }, - { - "description": "ransomware", - "uuid": "1b14e605-c8ce-4281-b09f-3c2478afc4f4", - "value": "SecretSystem" - }, - { - "description": "ransomware", - "uuid": "e0e111d1-8499-427d-aa37-41f1e52da79d", - "value": "SecureCryptor" - }, - { - "description": "ransomware", - "uuid": "5142f162-d123-4eca-a428-86033d9d60e0", - "value": "SeginChile" - }, - { - "description": "ransomware", - "uuid": "7e9924c3-f166-40be-b1c5-85011b77a7f2", - "value": "SEND.ID.TO" - }, - { - "description": "ransomware", - "uuid": "db6208a6-16a6-49fa-9259-ccd7626719f9", - "value": "Seon" - }, - { - "description": "ransomware", - "uuid": "de8ddc1c-3e86-46e9-abc5-4409257dd174", - "value": "Sepsis" - }, - { - "description": "ransomware", - "uuid": "75b0d6cd-477c-415b-bf3a-fd8181ea6747", - "value": "SepSys" - }, - { - "description": "ransomware", - "uuid": "8e0a2826-279a-4d7f-901f-223b65d556e2", - "value": "Shadi" - }, - { - "description": "ransomware", - "uuid": "a6a80481-0c0b-470d-bdc4-a35f75c6ec2e", - "value": "ShadowCryptor" - }, - { - "description": "ransomware", - "uuid": "14162500-23ce-47e5-8375-664516f2bf3c", - "value": "ShinigamiLocker" - }, - { - "description": "ransomware", - "uuid": "a7b363ef-7dd6-4df4-81c0-299670c11240", - "value": "ShkolotaCrypt" - }, - { - "description": "ransomware", - "uuid": "0e492b45-03c8-4f87-9038-4d37c7203b18", - "value": "Shrug" - }, - { - "description": "ransomware", - "uuid": "95b099a1-6549-4bf7-a895-3c06259ea000", - "value": "Shutdown57" - }, - { - "description": "ransomware", - "uuid": "21d4caeb-96e4-4564-8d62-6d7521b0d8ec", - "value": "ShutUpAndDance" - }, - { - "description": "ransomware", - "uuid": "92e5861f-5b20-4401-a75f-f5120269b827", - "value": "Sifreli 2017" - }, - { - "description": "ransomware", - "uuid": "87372df7-0fa1-4d1e-bf76-4cfdcdced997", - "value": "Sifreli 2019" - }, - { - "description": "ransomware", - "uuid": "364013f9-15d2-41c0-b458-fd4085466151", - "value": "SifreCozucu" - }, - { - "description": "ransomware", - "uuid": "939e7780-5c6e-43f4-9710-c0c219762bc9", - "value": "SilentSpring" - }, - { - "description": "ransomware", - "uuid": "c3a9d2d0-d239-40af-86cc-51457ed82b46", - "value": "SintaLocker" - }, - { - "description": "ransomware", - "uuid": "7c36b38e-6851-402b-93cd-195e029cba84", - "value": "Skull" - }, - { - "description": "ransomware", - "uuid": "fe5ea390-fe3a-4ec9-b0f6-8365c525f5be", - "value": "Skull HT" - }, - { - "description": "ransomware", - "uuid": "0d3634a3-1766-4b49-8ceb-2274ca2048af", - "value": "SkyStars" - }, - { - "description": "ransomware", - "uuid": "eae70261-6efc-424f-829f-4d179c7a75ae", - "value": "SlankCryptor" - }, - { - "description": "ransomware", - "uuid": "787ea4ce-23ab-464e-9dd8-bb6d24b0c481", - "value": "Snake-Ekans" - }, - { - "description": "ransomware", - "uuid": "92d45020-2aa0-49ac-8e71-be8f3a3f79eb", - "value": "SnakeLocker" - }, - { - "description": "ransomware", - "uuid": "1a58eeac-26dc-40e6-8182-22cd461ba736", - "value": "Snatch" - }, - { - "description": "ransomware", - "uuid": "f0a26e38-d67c-4215-8a9d-1723ac984d62", - "value": "SnowPicnic" - }, - { - "description": "ransomware", - "uuid": "f2125a86-a23d-4165-a6b7-821db3b48b95", - "value": "SoFucked" - }, - { - "description": "ransomware", - "uuid": "e065c7cc-061d-43a8-9668-1aa187e0fd52", - "value": "SOLO" - }, - { - "description": "ransomware", - "uuid": "48f18fa2-7dea-4bdf-8736-253672b62140", - "value": "Somik1" - }, - { - "description": "ransomware", - "uuid": "b5f99a93-0c4f-491d-a36a-617d892b5e38", - "value": "Sorry HT" - }, - { - "description": "ransomware", - "uuid": "2fab1ada-2e01-4704-b4d8-e3bb75e6488b", - "value": "SpartCrypt" - }, - { - "description": "ransomware", - "uuid": "1e968067-dd8f-4c15-a756-4f572a0ee2cf", - "value": "Spectre" - }, - { - "description": "ransomware", - "uuid": "dbe1f272-07c0-4189-ab91-4a6ee7d1ee9a", - "value": "Sphinx" - }, - { - "description": "ransomware", - "uuid": "9dad4770-3fd8-48e8-8dd3-bac621f9932a", - "value": "Spiteful Doubletake" - }, - { - "description": "ransomware", - "uuid": "a73abf3d-abda-4916-9401-8c522f87de7c", - "value": "SpongeBob" - }, - { - "description": "ransomware", - "uuid": "5eacbcf2-84b9-4467-a8de-4c8e9af2c840", - "value": "StalinLocker" - }, - { - "description": "ransomware", - "uuid": "6a9f0f9f-2033-4361-918b-fbfa1cac5e9b", - "value": "Stinger" - }, - { - "description": "ransomware", - "uuid": "e6b1ec39-e118-47d2-9205-468c87be86c2", - "value": "Storm" - }, - { - "description": "ransomware", - "uuid": "c6ab1853-d980-4eb8-b2d5-5c22d9eb882a", - "value": "StrawHat" - }, - { - "description": "ransomware", - "uuid": "928e5d57-8029-4300-be0a-5e6e43c220dd", - "value": "Streamer" - }, - { - "description": "ransomware", - "uuid": "d018d87e-4baa-45bd-880b-496c18726da3", - "value": "Striked" - }, - { - "description": "ransomware", - "uuid": "1ae8b4dd-eaef-4181-a699-02536aece63d", - "value": "Stroman" - }, - { - "description": "ransomware", - "uuid": "8371370f-8d53-4e90-95f7-e20540f5d052", - "value": "Stupid" - }, - { - "description": "ransomware", - "uuid": "b8826051-f533-4e70-b59e-166009946ee3", - "value": "StupidJapan" - }, - { - "description": "ransomware", - "uuid": "4d1c8d02-f3e2-4a95-8ca2-f3665ec6cc8d", - "value": "Styver" - }, - { - "description": "ransomware", - "uuid": "5039d334-c737-4d5b-941c-38a714a014c2", - "value": "Styx" - }, - { - "description": "ransomware", - "uuid": "41ee30d0-4c67-4445-990b-07c3c8f1aa28", - "value": "SuperB" - }, - { - "description": "ransomware", - "uuid": "f379af94-1826-41bb-a879-ff84a1319848", - "value": "SuperCrypt" - }, - { - "description": "ransomware", - "uuid": "f3673646-cfd7-4b6e-bd43-b3366d3391d9", - "value": "Suri" - }, - { - "description": "ransomware", - "uuid": "60561968-40ba-44b6-9ef5-5577c2422f72", - "value": "Symbiom" - }, - { - "description": "ransomware", - "uuid": "59863099-6ef0-4fad-87cb-adf21d22ace4", - "value": "SymmyWare" - }, - { - "description": "ransomware", - "uuid": "b779b4c0-f32c-4815-bcdf-b81f44a5efd0", - "value": "Syrk" - }, - { - "description": "ransomware", - "uuid": "a1bae9e1-2eed-4004-b289-b572936450a3", - "value": "SYSDOWN" - }, - { - "description": "ransomware", - "uuid": "ea3f6dc9-4afe-43c6-be84-1ba9c752c9c6", - "value": "SystemCrypter" - }, - { - "description": "ransomware", - "uuid": "561090ca-d8a6-43f8-acbb-c2d58d422cbd", - "value": "T1Happy" - }, - { - "description": "ransomware", - "uuid": "dcfb11cf-bc62-4c2c-9ff8-f4c019c1141d", - "value": "Takahiro Locker" - }, - { - "description": "ransomware", - "uuid": "4945d7b7-33a7-4e41-94ba-f55650f336e7", - "value": "TBHRanso" - }, - { - "description": "ransomware", - "uuid": "02467be1-ac0d-4fcd-b2b9-0d0c7d337e06", - "value": "Teamo" - }, - { - "description": "ransomware", - "uuid": "12622e89-46d4-4cd5-95be-c3a2d12e8a18", - "value": "Tear Dr0p" - }, - { - "description": "ransomware", - "uuid": "6ee1b6e3-dac1-483b-aa8c-6afe4433e1ed", - "value": "Technicy" - }, - { - "description": "ransomware", - "uuid": "db9aa4f1-5f54-4bed-9f7a-a19e906f94b4", - "value": "TeslaWare" - }, - { - "description": "ransomware", - "uuid": "d5d35c4f-ebde-43ae-acfc-d41c06210893", - "value": "TFlower" - }, - { - "description": "ransomware", - "uuid": "9867ec9e-a772-4c70-81dc-1517330e58bd", - "value": "The Brotherhood" - }, - { - "description": "ransomware", - "uuid": "cafb301d-098f-40d3-92c7-722b2cc15172", - "value": "The Magic" - }, - { - "description": "ransomware", - "uuid": "8ab31008-966e-4ad5-88a2-9e820b814292", - "value": "TheCursedMurderer" - }, - { - "description": "ransomware", - "uuid": "3ec11602-d4df-4341-a9f0-91caf2be1cc0", - "value": "TheDarkEncryptor" - }, - { - "description": "ransomware", - "uuid": "3ecf7a76-9e37-4d36-9dda-be8d0a38d56a", - "value": "Thor" - }, - { - "description": "ransomware", - "uuid": "6c01d67f-2d59-45ae-a5ba-decef1f2cc0d", - "value": "THT" - }, - { - "description": "ransomware", - "uuid": "630d46fe-306d-49fa-b2e4-9f85f8b86000", - "value": "ThunderCrypt" - }, - { - "description": "ransomware", - "uuid": "772f6749-a753-42af-8442-e6526f8b9a2a", - "value": "Tk" - }, - { - "description": "ransomware", - "uuid": "904fc008-64f6-4adf-863e-f5b6b63df65c", - "value": "Torchwood" - }, - { - "description": "ransomware", - "uuid": "dcf0947c-15f3-438c-97e0-ec65d63b80bb", - "value": "TorLocker" - }, - { - "description": "ransomware", - "uuid": "483cae7f-4554-46db-8bbc-223881ae9a1c", - "value": "TotalWipeOut" - }, - { - "description": "ransomware", - "uuid": "abdb9c59-c07b-4701-8208-e6a0cf9efe98", - "value": "TPS1.0" - }, - { - "description": "ransomware", - "uuid": "95d5eba2-dbb6-4527-9dee-ba13d1c9ac00", - "value": "Trick-Or-Treat" - }, - { - "description": "ransomware", - "uuid": "6853449b-8b09-43be-96dc-26b16b4d421b", - "value": "Trojan-Syria" - }, - { - "description": "ransomware", - "uuid": "18c91134-1df6-4853-a1c2-c8424137f2e6", - "value": "TrumpHead" - }, - { - "description": "ransomware", - "uuid": "90c6daf8-8212-4ea8-9b59-af49b290b3b9", - "value": "TurkStatik" - }, - { - "description": "ransomware", - "uuid": "93277946-177a-4f92-833d-30db9d432656", - "value": "Tyrant" - }, - { - "description": "ransomware", - "uuid": "0407e98d-cd3e-42e1-8daf-3c51d2e4906a", - "value": "UCCU" - }, - { - "description": "ransomware", - "uuid": "ba4f3704-cb2d-4a12-8d81-c825063aaaca", - "value": "Ukash" - }, - { - "description": "ransomware", - "uuid": "fbbb3784-ddf9-447a-91d8-e155317edd87", - "value": "Ultimo HT" - }, - { - "description": "ransomware", - "uuid": "911e63bc-ab09-4da1-8db7-2ad9354eafee", - "value": "UltraCrypter" - }, - { - "description": "ransomware", - "uuid": "a9695d8a-9d83-4ae0-9460-f4f56c41ed90", - "value": "Unikey" - }, - { - "description": "ransomware", - "uuid": "5ee8d6db-8a82-40ee-9e8e-a96795b3fee0", - "value": "Unknown Crypted" - }, - { - "description": "ransomware", - "uuid": "348fda47-e254-479e-b702-ebefda3f490d", - "value": "Unknown Lock" - }, - { - "description": "ransomware", - "uuid": "b73d6fd8-7707-451a-a5cb-0425289b02be", - "value": "Unknown XTBL" - }, - { - "description": "ransomware", - "uuid": "f94e3dba-cdd6-438e-bc7e-b71af6e8e161", - "value": "Unlckr" - }, - { - "description": "ransomware", - "uuid": "15140e19-f09e-4543-9a4c-b0f0e96860fe", - "value": "UNNAM3D" - }, - { - "description": "ransomware", - "uuid": "d77b1546-d37d-47ed-9a46-52892bdbd639", - "value": "Unnamed Bin" - }, - { - "description": "ransomware", - "uuid": "2fe11a8a-dfc3-41c3-891f-365a10a1debd", - "value": "Unrans" - }, - { - "description": "ransomware", - "uuid": "10666f8c-9e0a-485e-88cc-98b993321d5f", - "value": "UselessDisk" - }, - { - "description": "ransomware", - "uuid": "f43f4c9a-5008-477c-9105-4d444c883caa", - "value": "UselessFiles" - }, - { - "description": "ransomware", - "uuid": "a6a04c23-9df3-47b9-9095-4b7f9799f51a", - "value": "USR0" - }, - { - "description": "ransomware", - "uuid": "edcc3607-b246-44ce-8878-5af1a09976ae", - "value": "Vaca" - }, - { - "description": "ransomware", - "uuid": "74a8637a-ac0d-45dd-91d5-326459f09cb5", - "value": "VCrypt" - }, - { - "description": "ransomware", - "uuid": "d1deeb03-5084-4b50-bb19-38d7bd36a42f", - "value": "vCrypt1" - }, - { - "description": "ransomware", - "uuid": "d9dd94aa-a646-40b3-a2d3-5870c6be66cf", - "value": "VegaLocker" - }, - { - "description": "ransomware", - "uuid": "1ccd6940-4eb7-416c-a0de-1fb672d93c80", - "value": "Velso" - }, - { - "description": "ransomware", - "uuid": "7fd558de-1dfe-432a-834b-3e2691ee7283", - "value": "Vendetta" - }, - { - "description": "ransomware", - "uuid": "3d71e8a0-d823-47c0-8a0d-62e35d348514", - "value": "VevoLocker" - }, - { - "description": "ransomware", - "uuid": "e089f805-8cc2-41d0-b67e-eae21d78bc6c", - "value": "VHD" - }, - { - "description": "ransomware", - "uuid": "99edd501-76ca-4492-a0a3-8e1c988be22a", - "value": "ViACrypt" - }, - { - "description": "ransomware", - "uuid": "777390e2-0d15-499a-8f87-5a5851cdbd09", - "value": "Viagra" - }, - { - "description": "ransomware", - "uuid": "7eb414f6-11d9-4424-b486-e1e379b6840f", - "value": "VideoBelle" - }, - { - "description": "ransomware", - "uuid": "38c94712-deed-470a-b784-0f4665aebf39", - "value": "ViiperWare" - }, - { - "description": "ransomware", - "uuid": "0fecef7e-a387-497f-bc26-9560fd943afb", - "value": "Viro" - }, - { - "description": "ransomware", - "uuid": "3f62e429-7e6d-41c5-b716-9eb2304e60dc", - "value": "ViroBotnet" - }, - { - "description": "ransomware", - "uuid": "fc8cc150-c2fb-40cd-9cca-638b8a091861", - "value": "VisionCrypt" - }, - { - "description": "ransomware", - "uuid": "dff0c92b-953d-4fef-8b36-f36906f806d2", - "value": "VMola" - }, - { - "description": "ransomware", - "uuid": "823e56de-7d4c-4914-a49b-524a5bb77b02", - "value": "VoidCrypt" - }, - { - "description": "ransomware", - "uuid": "1da33eaf-096e-4076-8676-23da3a97ed74", - "value": "Vulston" - }, - { - "description": "ransomware", - "uuid": "a5d35c2d-7d06-4539-a4f7-75499663d152", - "value": "Waffle" - }, - { - "description": "ransomware", - "uuid": "26aec13a-eaf2-4adb-9c67-e6ae8f318a0c", - "value": "Waiting" - }, - { - "description": "ransomware", - "uuid": "e5b2a647-0107-4309-9695-c7bb7859cf4c", - "value": "Waldo" - }, - { - "description": "ransomware", - "uuid": "a3be0f12-ece5-4bdb-bcb6-1f5732eb5735", - "value": "Wanna Decryptor Portuguese" - }, - { - "description": "ransomware", - "uuid": "45259e4f-7c68-4e9a-86af-078607181a84", - "value": "WannabeHappy" - }, - { - "description": "ransomware", - "uuid": "30a56d79-1dee-401e-ad3d-3ea939c4efde", - "value": "WannaCash" - }, - { - "description": "ransomware", - "uuid": "870836be-0534-437e-a25a-7f1e70f9f394", - "value": "WannaDie" - }, - { - "description": "ransomware", - "uuid": "b222ca29-29b1-4aaa-a709-a3730a70216a", - "value": "WannaPeace" - }, - { - "description": "ransomware", - "uuid": "4dd51f0f-ad6b-4117-b071-505ec4b71730", - "value": "WannaSpam" - }, - { - "description": "ransomware", - "uuid": "9540bd2d-638b-4e79-a231-6f06b055c916", - "value": "Want Money" - }, - { - "description": "ransomware", - "uuid": "0ca42fde-477c-459d-89a6-bed041a73b70", - "value": "Wesker" - }, - { - "description": "ransomware", - "uuid": "5e678363-c42e-4852-9a2e-90212310a522", - "value": "WhatAFuck" - }, - { - "description": "ransomware", - "uuid": "305b6505-1186-43c8-acd9-431322287ec6", - "value": "WhyCry" - }, - { - "description": "ransomware", - "uuid": "cb343570-c8a0-4bb6-ba3b-88126449593e", - "value": "Windows10" - }, - { - "description": "ransomware", - "uuid": "99a8b639-1b06-4e4b-9994-a6e4d0601341", - "value": "WininiCrypt" - }, - { - "description": "ransomware", - "uuid": "1942a99a-5c5a-49ef-8c6d-0cb6b0fb082b", - "value": "Winsecure" - }, - { - "description": "ransomware", - "uuid": "8ec00fe5-475b-47bc-a7fc-b470d15aaa75", - "value": "WinUpdatesDisabler" - }, - { - "description": "ransomware", - "uuid": "f14af77c-5a98-4840-953c-2f37af8cdcc5", - "value": "WTDI" - }, - { - "description": "ransomware", - "uuid": "39bcd377-24cb-42f4-8f2a-2aa17d5171dc", - "value": "X Locker 5.0" - }, - { - "description": "ransomware", - "uuid": "78e05406-ce59-478a-bf1e-1b1abe22e116", - "value": "XCry" - }, - { - "description": "ransomware", - "uuid": "88f4f772-8c6e-4201-92aa-819c5e7af5c1", - "value": "XD" - }, - { - "description": "ransomware", - "uuid": "9582a86c-c20d-4e1f-a124-bf2c6d8adf33", - "value": "XData" - }, - { - "description": "ransomware", - "uuid": "4272cc4a-9d93-4712-b641-b7f4fc9f86bc", - "value": "XeroWare" - }, - { - "description": "ransomware", - "uuid": "5ecc109c-9f04-4e56-86c4-83b37181e75b", - "value": "Xlockr" - }, - { - "description": "ransomware", - "uuid": "a0c2b579-20f0-4357-8a01-596ce20db48a", - "value": "XmdXtazX" - }, - { - "description": "ransomware", - "uuid": "95d00a69-c048-48c3-bc6b-fa6a655d8ff3", - "value": "Xncrypt" - }, - { - "description": "ransomware", - "uuid": "d650da35-7ad7-417a-902a-16ea55bd1126", - "value": "XRat" - }, - { - "description": "ransomware", - "uuid": "f5c46d3f-404b-4640-9892-005f845d33a2", - "value": "XyuEncrypt" - }, - { - "description": "ransomware", - "uuid": "c08fd941-e54c-4ac6-b94a-fc9b5c9617da", - "value": "xXLecXx" - }, - { - "description": "ransomware", - "uuid": "ebfa8988-8063-4e3c-a635-7da898389aa4", - "value": "Yatron" - }, - { - "description": "ransomware", - "uuid": "d6791998-5c0a-4943-bda5-b378d1326a13", - "value": "Yoshikada" - }, - { - "description": "ransomware", - "uuid": "e32b8df2-6f03-4232-b64a-2de14b5642f3", - "value": "YYYYBJQOQDU" - }, - { - "description": "ransomware", - "uuid": "2f6d77c5-54df-4997-b82c-ca54d6948d6f", - "value": "ZariqaCrypt" - }, - { - "description": "ransomware", - "uuid": "463d17d4-e35e-4614-9247-47a3a50a8cda", - "value": "Zelta Free" - }, - { - "description": "ransomware", - "uuid": "fee8e9fa-68b9-4b69-bd62-6213971e7e10", - "value": "ZenCrypt" - }, - { - "description": "ransomware", - "uuid": "5e3a2958-6922-465e-bc36-3b6e59ad1bc1", - "value": "Zeoticus" - }, - { - "description": "ransomware", - "uuid": "bc62429c-1bf7-42c0-997d-d8c2f80355de", - "value": "Zeppelin" - }, - { - "description": "ransomware", - "uuid": "90ac4150-aab9-44a2-bd56-2bcfa773798b", - "value": "Zero-Fucks" - }, - { - "description": "ransomware", - "uuid": "9296d2bc-ec26-4724-88b4-82ab682ed11e", - "value": "ZeroLocker" - }, - { - "description": "ransomware", - "uuid": "03686533-7339-4401-b90d-1125eeffa07f", - "value": "Zeronine" - }, - { - "description": "ransomware", - "uuid": "4ff2a1ff-a35e-4d3a-a132-2dcefa2995f7", - "value": "ZeroRansom" - }, - { - "description": "ransomware", - "uuid": "2147b5a8-2f4a-433c-95aa-cdeb4349c542", - "value": "Zilla" - }, - { - "description": "ransomware", - "uuid": "ae9ec6c3-570f-41fc-ac18-5b129976727a", - "value": "ZimbraCryptor" - }, - { - "description": "ransomware", - "uuid": "0dfbed7c-66c5-4309-b8ba-7c7a6e659512", - "value": "ZipLocker" - }, - { - "description": "ransomware", - "uuid": "774e5809-2d72-4c3d-a28b-5c51f17f1981", - "value": "Zipper" - }, - { - "description": "ransomware", - "uuid": "a67eedaf-84c5-42ed-86fe-853c76599fe5", - "value": "Zoldon" - }, - { - "description": "ransomware", - "uuid": "03e34bcf-af8b-429d-ac66-aeff844e8fd6", - "value": "ZorgoCry" - }, - { - "description": "ransomware", - "uuid": "78541326-4aaa-4eda-8f55-bf21bb2537ab", - "value": "Smaug" - }, - { - "description": "ransomware", - "uuid": "e3cce543-64b0-4f7a-a176-f1ddc429da3f", - "value": "GammA" - }, - { - "description": "ransomware", - "uuid": "c35de33c-8f7c-41f3-9b74-6da34a0d31c6", - "value": "BlackMoon" - }, - { - "description": "ransomware", - "uuid": "ab33547b-2b6c-47ae-8fca-9747735b0955", - "value": "MilkmanVictory" - }, - { - "description": "ransomware", - "uuid": "1263f5e9-7073-443b-a884-caf9ebf47a1a", - "value": "Dragoncyber" - }, - { - "description": "ransomware", - "uuid": "61513ee1-4667-43eb-831a-3e01d8e1039f", - "value": "Solider" - }, - { - "description": "ransomware", - "uuid": "a65bde28-b74c-4ec5-ae20-01cbe101b025", - "value": "Biglock" - }, - { - "description": "ransomware", - "uuid": "c2880897-759e-4cbf-8d08-a3418567a33c", - "value": "Immuni" - }, - { - "description": "ransomware", - "uuid": "d848ca6f-c935-4dba-b706-bd06be094a87", - "value": "Black claw" - }, - { - "description": "ransomware", - "uuid": "b6096de6-c831-4a64-9108-e3fcfc7fcc44", - "value": "Banks1" - }, - { - "description": "ransomware", - "uuid": "9683775c-7d36-4a5a-9580-1038ed17d9d2", - "value": "UnluckyWare" - }, - { - "description": "ransomware", - "uuid": "7d949282-005f-45de-96b3-5584a1114cd6", - "value": "Zorab" - }, - { - "description": "ransomware", - "uuid": "b56a89d1-1748-42a0-8a78-02e882a219a9", - "value": "FonixCrypter" - }, - { - "description": "ransomware", - "uuid": "ab0f5636-38cf-4c89-a090-df4f006bd47b", - "value": "LickyAgent" - }, - { - "description": "ransomware", - "uuid": "2c6fdb78-08cc-4199-992d-0b8c8a6b1c46", - "value": "Avaddon" - }, - { - "description": "ransomware", - "uuid": "d52ba288-4bcc-4f52-be6c-0d9cfadbf194", - "value": "DualShot" - }, - { - "description": "ransomware", - "uuid": "e68a3736-1d87-4a77-9814-b23c65cee3c3", - "value": "RNS" - }, - { - "description": "ransomware", - "uuid": "b1126047-eaaa-4e2f-abc9-f64faa84d692", - "value": "Such_Crypt" - }, - { - "description": "ransomware", - "uuid": "c64d6b5d-44a1-461e-acc6-2b4571f6163d", - "value": "20dfs" - }, - { - "description": "ransomware", - "uuid": "cfa9c2ee-6a2f-4cd4-849f-bcf8e9aa77a7", - "value": "CryDroid" - }, - { - "description": "ransomware", - "uuid": "6f011a57-6a70-4e2a-9a51-36d9032bef05", - "value": "TomNom" - }, - { - "description": "ransomware", - "uuid": "ada0a2d1-f595-4988-b87a-623c5581bbad", - "value": "Yogynicof" - }, - { - "description": "ransomware", - "uuid": "d160c549-3cf8-4f20-b041-8d775469a566", - "value": "CobraLocker" - }, - { - "description": "ransomware", - "uuid": "ca9a3c5c-ef8e-4e09-bd91-0347a6967837", - "value": "PL" - }, - { - "description": "ransomware", - "uuid": "ed6f4c24-a2eb-4395-ae76-4d4992b21f5b", - "value": "CryCryptor" - }, - { - "description": "ransomware", - "uuid": "d1c43e2b-75a5-4d75-a8b7-b46fe106ed87", - "value": "Blocky" - }, - { - "description": "ransomware", - "uuid": "b7d9e0c2-e772-41e0-9202-5df2bcff9022", - "value": "OhNo-FakePDF" - }, - { - "description": "ransomware", - "uuid": "455b864e-47c0-419f-9c0c-a75bac6d5e84", - "value": "Try2Cry" - }, - { - "description": "ransomware", - "uuid": "5e1df833-e4de-44a9-8728-1681a6e6afbc", - "value": "LolKek" - }, - { - "description": "ransomware", - "uuid": "165949bf-bc59-43c8-a9b7-d281da5688ee", - "value": "FlowEncrypt" - }, - { - "description": "ransomware", - "uuid": "3ae97d00-4b38-4f81-a055-a1057e3cebae", - "value": "WhoLocker" - }, - { - "description": "ransomware", - "uuid": "ad010794-bdac-4157-adba-e87014a29708", - "value": "Pojie" - }, - { - "description": "ransomware", - "uuid": "c795358a-c462-48f0-a5ff-9bdc1dd869e5", - "value": "Aris Locker" - }, - { - "description": "ransomware", - "uuid": "7750a0ed-e17b-4eaf-97f1-ddf097c48858", - "value": "EduRansom" - }, - { - "description": "ransomware", - "uuid": "db954a2d-4602-4722-977d-3b147ebc1858", - "value": "Fastwind" - }, - { - "description": "ransomware", - "uuid": "51600819-3b88-43a9-b64e-d08bf5d29f7c", - "value": "Silvertor" - }, - { - "description": "ransomware", - "uuid": "b8b0933a-896a-45d1-8284-ebc55dff1f98", - "value": "Exorcist" - }, - { - "description": "ransomware", - "uuid": "df5ef12b-c0e3-4069-beaa-e84ea953befc", - "value": "WyvernLocker" - }, - { - "description": "ransomware", - "uuid": "58d0f5cf-5e71-44dc-b493-b0d3c0724587", - "value": "Ensiko" - }, - { - "description": "ransomware", - "uuid": "d667e11f-95d0-4c44-a0c6-b6ab617c307f", - "value": "Django" - }, - { - "description": "ransomware", - "uuid": "2c754dfc-0748-47d7-8853-652c1d6a93a7", - "value": "RansomBlox" - }, - { - "description": "ransomware", - "uuid": "a378ddf1-5981-4e76-8672-60dd4cb67dc1", - "value": "BitRansomware" - }, - { - "description": "ransomware", - "uuid": "e9cd52e1-b3e0-4da9-b969-4a3947f3f6bf", - "value": "AESMew" - }, - { - "description": "ransomware", - "uuid": "4cd34987-7b49-4a75-8668-a02498b9b1ac", - "value": "DeathOfShadow" - }, - { - "description": "ransomware", - "uuid": "9acc2bd8-9215-4795-bf2b-c4281a8ca697", - "value": "XMRLocker" - }, - { - "description": "ransomware", - "uuid": "0aada732-3b59-4410-a043-5a190d391927", - "value": "WinWord64" - }, - { - "description": "ransomware", - "uuid": "937d3070-7fc6-4967-98bc-17acb0c8da8e", - "value": "ThunderX" - }, - { - "description": "ransomware", - "uuid": "7513650c-ba09-49bf-b011-d2974c7ae023", - "value": "Mountlocket" - }, - { - "description": "ransomware", - "uuid": "09fac901-8fcf-4faa-b1e3-96407433d0f2", - "value": "Gladius" - }, - { - "description": "ransomware", - "uuid": "1ff34e4a-a205-493f-bdd0-2212d80fd83c", - "value": "Cyrat" - }, - { - "description": "ransomware", - "uuid": "705e03d1-b0c9-4c0b-9b10-fb751e09a020", - "value": "Crypt32" - }, - { - "description": "ransomware", - "uuid": "16ebc67f-96d2-4497-84da-a05713352aba", - "value": "BizHack" - }, - { - "description": "ransomware", - "uuid": "971bdbfe-d55d-410f-9b07-57ba69027eb8", - "value": "Geneve" - }, - { - "description": "ransomware", - "uuid": "361a35bc-c952-41ad-bd27-c32b690aa9e3", - "value": "Z3" - }, - { - "description": "ransomware", - "uuid": "e723285e-14ff-4d25-97c3-43e73168d606", - "value": "Leakthemall" - }, - { - "description": "ransomware", - "uuid": "201eff54-d41e-4f70-916c-5dfb9301730a", - "value": "Conti" - }, - { - "description": "ransomware", - "uuid": "f3d28719-fa72-42c3-b0fe-cda484abbaf9", - "value": "Makop" - }, - { - "description": "ransomware", - "uuid": "b0552a9f-8820-48c3-a75b-158063f17e1b", - "value": "Best Crypt" - }, - { - "description": "ransomware", - "uuid": "784c93bb-4522-4988-92c0-fef89ff6086d", - "value": "Consciousness" - }, - { - "description": "ransomware", - "uuid": "28d7d7e6-3803-4e77-bd89-8a0921a55c17", - "value": "Flamingo" - }, - { - "description": "ransomware", - "uuid": "89346526-4f9d-4369-a1a2-53974a97a651", - "value": "PewPew" - }, - { - "description": "ransomware", - "uuid": "9684f0dc-2c9d-46e3-a12f-65ea85a678e5", - "value": "DogeCrypt" - }, - { - "description": "ransomware", - "uuid": "47354b68-52c9-4750-b783-97c278ddb6a2", - "value": "Badbeeteam" - }, - { - "description": "ransomware", - "uuid": "e6b40e6b-7c3e-453c-a250-577f4b8a1a7c", - "value": "Solve" - }, - { - "description": "ransomware", - "uuid": "6f7c24e3-b7e6-483c-92f0-99bf562f6397", - "value": "RenameX12" - }, - { - "description": "ransomware", - "uuid": "e3c82188-6f63-48e1-ace8-e93484994792", - "value": "Zhen" - }, - { - "description": "ransomware", - "uuid": "e5ef8579-a215-4450-8294-c887f3d62476", - "value": "Datacloud" - }, - { - "description": "ransomware", - "uuid": "d511beb8-69c6-4ad8-aa82-fb7b56f467a5", - "value": "Ironcat" - }, - { - "description": "ransomware", - "uuid": "ea521e5d-0908-4bb4-8111-b27f56b8fb8d", - "value": "Dusk" - }, - { - "description": "ransomware", - "uuid": "966b504a-b032-4d99-80fa-5008228b2926", - "value": "Cutekitty" - }, - { - "description": "ransomware", - "uuid": "3cc0e0d6-2b19-4505-8f2f-11456efeda8f", - "value": "Babax" - }, - { - "description": "ransomware", - "uuid": "a7219d8e-e616-4808-8d5d-6eafe423405a", - "value": "Eyecry" - }, - { - "description": "ransomware", - "uuid": "9f23a356-8ae8-40b2-bbde-d2f4ba62a883", - "value": "Osno" - }, - { - "description": "ransomware", - "uuid": "1a49c0c2-3b66-4832-bf9c-d5624e6a5aaa", - "value": "Loki" - }, - { - "description": "ransomware", - "uuid": "c4390e31-fdbd-44d9-babf-adc2b20a57ff", - "value": "WoodRat" - }, - { - "description": "ransomware", - "uuid": "6d1ba8c7-3a86-4ec5-bfdf-f647c6fe984b", - "value": "Curator" - }, - { - "description": "ransomware", - "uuid": "31c20516-d4ee-46fb-a020-ccc1b44177b7", - "value": "32aa" - }, - { - "description": "ransomware", - "uuid": "6ac0f7e3-eebd-4112-a915-b069604c6d2b", - "value": "Vaggen" - }, - { - "description": "ransomware", - "uuid": "fb98368c-79fb-4d34-a7e0-c4cc9847bce0", - "value": "Clay" - }, - { - "description": "ransomware", - "uuid": "7b2f9d2c-d96a-4515-b57d-cc1cff35de3a", - "value": "Pizhon" - }, - { - "description": "ransomware", - "uuid": "8439a797-4d81-4b8c-b278-3c41c640294f", - "value": "InstallPay" - }, - { - "description": "ransomware", - "uuid": "ff711485-e052-4ca0-934a-748a7a5d6f4c", - "value": "MetadataBin" - }, - { - "description": "ransomware", - "uuid": "bd743e59-1a2a-40ad-9cd4-d1e519d3b91d", - "value": "TechandStrat" - }, - { - "description": "ransomware", - "uuid": "af35e406-7af3-46f1-b32d-305f9711f645", - "value": "Mars" - }, - { - "description": "ransomware", - "uuid": "bee837e2-8bdb-4291-a267-4211bdc2a309", - "value": "Scatterbrain" - }, - { - "description": "ransomware", - "uuid": "55d3f7c0-7aa8-4b0e-b0f9-86dd68c78968", - "value": "CCECrypt" - }, - { - "description": "ransomware", - "uuid": "5de1dec7-749e-42ad-b0bf-68d5d774d5be", - "value": "SZ40" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "678bc24d-a5c3-4ddd-9292-40958afa3492", - "value": "Pay2Key" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "ae288b5d-062c-4a11-ba81-14794dc6127f", - "value": "Tripoli" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "dcc12d6f-d59f-4451-999d-7728bf4e95aa", - "value": "Devos" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "63397164-fee2-4662-afac-cc651b0426cb", - "value": "HowAreYou" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "4be906e7-b6db-453f-8f9b-a8d8d9b29f4b", - "value": "SifreCikis" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "1bdafae9-51cd-4384-8ee7-774c9db7820f", - "value": "68-Random-HEX" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "a536a6bd-f567-4631-bdc7-ac38fd9faf81", - "value": "RedRoman" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "ce9b4949-aa84-46fe-a532-2d8b7846d1f5", - "value": "MXX" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "5553296d-2fe5-490b-bb16-bc2432ede8be", - "value": "Exerwa CTF" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "022c995a-f1ba-498f-b67e-92ef01fd06a3", - "value": "HelloKitty" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "1496ec2f-76b0-425b-badc-8b7749c7e370", - "value": "HolidayCheer" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "d4733b99-e1d7-4101-9653-65d8ed73bd47", - "value": "Joker Korean" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "c0222809-cffa-467b-a9b1-b7caaf238b14", - "value": "VenomRAT" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "2a2f3d8f-83c1-490b-94d1-b56b90e81d19", - "value": "FileEngineering" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "uuid": "77714a96-6242-416a-ba6e-a1080e71cd81", - "value": "LandSlide" - }, - { - "description": "ransomware", - "meta": { - "date": "November 2020" - }, - "related": [ - { - "dest-uuid": "681f212a-af1b-4e40-a718-81b0dc46dc52", - "tags": [ - "estimative-language:likelihood-probability=\"likely\"" - ], - "type": "similar" - } - ], - "uuid": "8fa6b51a-a48d-48dc-87ec-cf0d30ad66e8", - "value": "Mobef-JustFun" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020", - "ransomnotes": [ - "All your files have been encrypted\n\nContact us to this email to decrypt your files:\nancrypted1@gmail.com\nIn case of of no answer in 24 hours contact the secondary email:\nancrypted1@gmail.com\n\nYou can unlock them by buying the special key generated for you\n\nFree decryption as guarantee\nBefore paying you can send us up to 5 files for free decryption. The total size of files must be less than 4Mb (non archived),and files should not contain valuable information. (databases,backups,large excel sheets, etc.)\n\n\nPayment is possible only with bitcoin\n\nHow to obtain bitcoins\nThe easoway to buy bitcoins is LocalBitcoins site. you have to register, click ?Buy bitcoins?, and select the seller by payment method and price.\nHttps://localbitcoins.com/buy_bitcoins\nAlso you can fund other places to buy Bitcoins and beginners guide here:\nHttp://www.coindesk.com/information/how-can-i-buy-bitcoins/\n\nAttention !!!\n1. Do not rename encrypted files.\n2. Do not try to decrypt your data using third party softwares, it may cause permanent data loss.\n3. Decryption or your files with the help of third parties may cause increased price(they add their fee to ours) or you can become a victim of a scam" - ], - "refs": [ - "https://malware-guide.com/blog/remove-amjixius-ransomware-restore-encrypted-files" - ], - "synonyms": [ - "Ancrypted" - ] - }, - "uuid": "1efe19b7-a8f3-455b-aefc-a41a5788bf2c", - "value": "Amjixius" - }, - { - "description": "ransomware", - "meta": { - "date": "Mars 2021" - }, - "uuid": "c99e4aee-03f7-4cb6-b1ce-2394d00d1472", - "value": "DearCry" - }, - { - "description": "ransomware", - "meta": { - "date": "Mars 2021" - }, - "uuid": "0353ecc5-849c-44a1-9ace-bff14e358c7a", - "value": "JoJoCrypter" - }, - { - "description": "ransomware", - "meta": { - "date": "Mars 2021" - }, - "uuid": "3742b551-b7e8-4256-81fa-137a05693bb8", - "value": "RunExeMemory" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "b0b690c4-b0d3-4e5e-a855-474f312287dc", - "value": "Pay2Decrypt" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "c7da6edc-dd6a-4e7b-8ce2-2f97a98f6efb", - "value": "Tortoise" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "401a8f57-7bf6-4a2a-834c-896bc29aa73f", - "value": "EPICALLY" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "52a907ab-f38b-4144-ba13-cab33adaab38", - "value": "Random30" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "419955fb-cfe6-4eba-b2ec-de53f4266e25", - "value": "Hog" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "f4c25d90-fea1-4bf5-8128-108f4ed279e4", - "value": "Steel" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "8a12618d-caf0-4b97-a4d8-fb475820d6f1", - "value": "JohnBorn" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "8018e133-c4c9-4a1b-bf39-5007c35c0a54", - "value": "Egalyty" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "b7e0a8c9-ffac-416e-8c8e-1670f3b3729f", - "value": "Namaste" - }, - { - "description": "ransomware", - "meta": { - "date": "Febuary 2021" - }, - "uuid": "570382c4-7b30-4f05-a385-e0691e0abfbc", - "value": "HDLocker" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "d2776f0d-29d6-45a2-be76-9072c52ce7cc", - "value": "Epsilon" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "34865f14-c5b4-42b8-9cc1-e1325dbe0d23", - "value": "DeroHE" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "29a61b85-4c63-46b0-bca0-32525ba1c56b", - "value": "Vovalex" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "93e45f39-ee69-4907-b7c7-2eb406313b53", - "value": "Bonsoir" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "91381710-823e-4eb6-a52f-28ab163638f3", - "value": "PulpFictionQuote" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "8fc25ce2-a5f7-49dc-8480-2a7a2cb60606", - "value": "NAS Data Compromiser" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "7f3e44d7-cccb-4fc7-86c6-006d25dc3c5d", - "value": "CNH" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "5a7d70c5-c5a2-4f00-be6d-a7499ca350f1", - "value": "Lucy" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020", - "synonyms": [ - "OctEncrypt" - ] - }, - "uuid": "e0189c0e-8da9-4e48-9c09-9cb8d8eb2a8b", - "value": "OCT" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "556f7792-ed79-42cf-9912-865319e10d48", - "value": "Pump" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "33edc2a9-231d-4a41-8dd8-ea9697dd0e13", - "value": "LuciferCrypt" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "28ca283a-221f-4e8a-bcc3-feddd67991dc", - "value": "Ziggy" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "0aed6d0e-6ecc-4295-a5ef-90389f1f00f9", - "value": "CoderCrypt" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "97ac3893-4331-454f-882f-1dcd9f2c6bcb", - "value": "BlueEagle" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "e8c800ce-c8e3-4176-87c9-8a0c48a9b5e4", - "value": "Povisomware" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "dd5712e1-efa8-4054-a5df-fdfdbc9c25b6", - "value": "JCrypt" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "9a2ecc67-6462-4d6e-9f18-eacc097ce6c7", - "value": "Uh-Oh" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "b539d0d8-1dad-4874-b743-e07063f8907e", - "value": "Mijnal" - }, - { - "meta": { - "date": "December 2020" - }, - "uuid": "440f9a8e-9837-433a-b2f3-c6a6914146ef", - "value": "16x" - }, - { - "description": "ransomware", - "meta": { - "date": "December 2020" - }, - "uuid": "ac805a25-0b35-4c3e-82a5-2c8d19a53294", - "value": "Lockedv1" - }, - { - "description": "ransomware", - "meta": { - "date": "JanuaryJ 2021" - }, - "uuid": "658dbbb2-c596-4ca0-a085-7b41f1fcebd0", - "value": "XD Locker" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "c47eb2fa-9fe2-42b8-8339-49e4de7296e2", - "value": "Knot" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "390fc4fc-9f46-480a-b114-aba898564c8a", - "value": "Parasite" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "9d43444d-205b-4fac-81a8-2affd49b1eb6", - "value": "Judge" - }, - { - "description": "ransomware", - "meta": { - "date": "January 2021" - }, - "uuid": "f84b92bb-d8e8-4ddd-848c-1a91df504e8e", - "value": "DEcovid19" - }, - { - "description": "Ragnarok is is a ransomware that targetscorporate networks in Big Game Huntingtargeted attacks. The ransomware is associated with 'double-extortion' tactic, stealing and publishing files on a data leak site (DLS).", - "meta": { - "encryption": "AES", - "extensions": [ - ".ragnarok", - ".ragnarok_cry" - ], - "refs": [ - "https://malpedia.caad.fkie.fraunhofer.de/details/win.ragnaro", - "https://borncity.com/win/2021/03/27/tu-darmstadt-opfer-der-ragnarok-ransomware/" - ] - }, - "uuid": "fe7e4df0-97b9-4dd2-b3f8-79404fc8272d", - "value": "Ragnarok" - } - ], - "version": 98 -} diff --git a/AxonIvyPortal/PortalTest/resources/testFile/sample-file.txt b/AxonIvyPortal/PortalTest/resources/testFile/sample-file.txt deleted file mode 100644 index 4fa0f1e08fb..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/sample-file.txt +++ /dev/null @@ -1 +0,0 @@ -This is a sample file using for upload test. \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-iframe.json b/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-iframe.json deleted file mode 100644 index 5d8f9589884..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-iframe.json +++ /dev/null @@ -1,25 +0,0 @@ -[{ - "id": "default-task-detail", - "widgets": [{ - "type": "information", - "layout": { - "x": 0, - "y": 0, - "w": 4, - "h": 10 - } - }, { - "type": "custom", - "layout": { - "x": 6, - "y": 0, - "w": 8, - "h": 6 - }, - "data": { - "url": "https://www.axonivy.com/" - } - } - ] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-panel.json b/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-panel.json deleted file mode 100644 index 4653f7fdd14..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-panel.json +++ /dev/null @@ -1,53 +0,0 @@ -[{ - "id": "default-task-detail", - "widgets": - [{ - "type": "information", - "layout": { - "x": 0, - "y": 4, - "w": 6, - "h": 12 - } - }, { - "type": "document", - "layout": { - "x": 6, - "y": 4, - "w": 6, - "h": 6 - } - }, { - "type": "history", - "layout": { - "x": 6, - "y": 10, - "w": 6, - "h": 6 - } - }, { - "type": "custom", - "layout": { - "x": 0, - "y": 0, - "w": 12, - "h": 4 - }, - "data": { - "type": "taskItemDetailCustomPanelTop" - } - }, { - "type": "custom", - "layout": { - "x": 0, - "y": 16, - "w": 12, - "h": 6 - }, - "data": { - "type": "taskItemDetailCustomPanelBottom" - } - } - ] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-process-iframe.json b/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-process-iframe.json deleted file mode 100644 index fc22515d86b..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/task-details-custom-process-iframe.json +++ /dev/null @@ -1,39 +0,0 @@ -[{ - "id": "default-task-detail", - "widgets": [{ - "type": "information", - "layout": { - "x": 0, - "y": 0, - "w": 6, - "h": 12 - } - }, { - "type": "history", - "layout": { - "x": 6, - "y": 6, - "w": 6, - "h": 6 - } - }, { - "type": "custom", - "layout": { - "x": 6, - "y": 0, - "w": 6, - "h": 6 - }, - "data": { - "processPath": "Start Processes/TaskDetailsCustomWidgetExample/invoiceDetails.ivp", - "params": { - "startedTaskId": "task.id", - "startedTaskCategory": "task.category", - "invoiceId": "000001573", - "invoiceDescription": "task.customFields.invoiceDescription" - } - } - } - ] - } -] diff --git a/AxonIvyPortal/PortalTest/resources/testFile/test-ms-word-extension.doc b/AxonIvyPortal/PortalTest/resources/testFile/test-ms-word-extension.doc deleted file mode 100644 index 7d6eb79752bf457230a4ca8b98adc7525e2db320..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9216 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 diff --git a/AxonIvyPortal/PortalTest/resources/testFile/test-no-files-with-js.pdf b/AxonIvyPortal/PortalTest/resources/testFile/test-no-files-with-js.pdf deleted file mode 100644 index 8c234f534d67ce7d260c0e338db1aae90cdd8eb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7462 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 diff --git a/AxonIvyPortal/PortalTest/resources/testFile/test-with-macro.xls b/AxonIvyPortal/PortalTest/resources/testFile/test-with-macro.xls deleted file mode 100644 index ccea22d52d9730dfe602786555426b1a200eefc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32256 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 MoUffp|GzEpzeosh)Bpeg diff --git a/AxonIvyPortal/PortalTest/resources/testFile/unsupportedExtension.abc b/AxonIvyPortal/PortalTest/resources/testFile/unsupportedExtension.abc deleted file mode 100644 index 0a901256855..00000000000 --- a/AxonIvyPortal/PortalTest/resources/testFile/unsupportedExtension.abc +++ /dev/null @@ -1 +0,0 @@ -Testing \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/src/portalTest/utils/CaseTestUtils.java b/AxonIvyPortal/PortalTest/src/portalTest/utils/CaseTestUtils.java deleted file mode 100644 index 5fc25684dda..00000000000 --- a/AxonIvyPortal/PortalTest/src/portalTest/utils/CaseTestUtils.java +++ /dev/null @@ -1,9 +0,0 @@ -package portalTest.utils; - -import ch.ivyteam.ivy.environment.Ivy; - -public class CaseTestUtils { - public static String findUUID(String caseId) { - return Ivy.wf().findCase(Long.valueOf(caseId)).uuid(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/service/HistoryServiceTest.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/service/HistoryServiceTest.java deleted file mode 100644 index 86c5d643e7e..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/service/HistoryServiceTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package ch.ivy.addon.portalkit.service; - -import static org.powermock.api.mockito.PowerMockito.mockStatic; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import ch.ivy.addon.portalkit.bo.History; -import ch.ivy.addon.portalkit.enums.AdditionalProperty; -import ch.ivy.addon.portalkit.util.UserUtils; -import ch.ivyteam.ivy.environment.Ivy; -import ch.ivyteam.ivy.security.IUser; -import ch.ivyteam.ivy.workflow.INote; -import ch.ivyteam.ivy.workflow.ITask; -import ch.ivyteam.ivy.workflow.TaskState; -import ch.ivyteam.ivy.workflow.custom.field.ICustomFields; -import ch.ivyteam.ivy.workflow.custom.field.ICustomStringField; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({Ivy.class, UserUtils.class}) -public class HistoryServiceTest { - - private static final String SYSTEM_USER_NAME = "SYSTEM"; - - @Test - public void testCreateHistoriesFromINotesAndITasks() { - mockStatic(UserUtils.class); - List tasks = new ArrayList<>(createTechnicalITasks()); - tasks.addAll(createITasks()); - List notes = new ArrayList<>(createTechnicalINotes()); - notes.addAll(createINotes()); - HistoryService historyService = new HistoryService(); - List histories = historyService.getHistories(tasks, notes, true, true); - Assert.assertEquals(2, histories.size()); - Assert.assertEquals(History.HistoryType.NOTE, histories.get(0).getType()); - Assert.assertEquals(History.HistoryType.TASK, histories.get(1).getType()); - - histories = historyService.getHistories(tasks, notes, true, false); - Assert.assertEquals(3, histories.size()); - Assert.assertEquals(History.HistoryType.NOTE, histories.get(0).getType()); - Assert.assertEquals(History.HistoryType.NOTE, histories.get(1).getType()); - Assert.assertEquals(History.HistoryType.TASK, histories.get(2).getType()); - - histories = historyService.getHistories(tasks, notes, false, true); - Assert.assertEquals(3, histories.size()); - Assert.assertEquals(History.HistoryType.NOTE, histories.get(0).getType()); - Assert.assertEquals(History.HistoryType.TASK, histories.get(1).getType()); - Assert.assertEquals(History.HistoryType.TASK, histories.get(2).getType()); - - histories = historyService.getHistories(tasks, notes, false, false); - Assert.assertEquals(4, histories.size()); - Assert.assertEquals(History.HistoryType.NOTE, histories.get(0).getType()); - Assert.assertEquals(History.HistoryType.NOTE, histories.get(1).getType()); - Assert.assertEquals(History.HistoryType.TASK, histories.get(2).getType()); - Assert.assertEquals(History.HistoryType.TASK, histories.get(3).getType()); - } - - private List createITasks() { - ITask mockTask = Mockito.mock(ITask.class); - ICustomFields customFields = Mockito.mock(ICustomFields.class); - ICustomStringField stringField = Mockito.mock(ICustomStringField.class); - Mockito.when(mockTask.getId()).thenReturn(Long.valueOf(4)); - Mockito.when(mockTask.getName()).thenReturn("Sample task"); - Mockito.when(mockTask.getState()).thenReturn(TaskState.SUSPENDED); - - Mockito.when(mockTask.getActivatorName()).thenReturn("demo"); - Mockito.when(mockTask.getStartTimestamp()).thenReturn(new Date()); - Mockito.when(mockTask.customFields()).thenReturn(customFields); - Mockito.when(mockTask.customFields().stringField(AdditionalProperty.ADHOC_EXPRESS_TASK.toString())).thenReturn(stringField); - return Arrays.asList(mockTask); - } - - private List createTechnicalITasks() { - ITask mockTask = Mockito.mock(ITask.class); - ICustomFields customFields = Mockito.mock(ICustomFields.class); - ICustomStringField stringField = Mockito.mock(ICustomStringField.class); - Mockito.when(mockTask.getId()).thenReturn(Long.valueOf(4)); - Mockito.when(mockTask.getName()).thenReturn("Sample task"); - Mockito.when(mockTask.getState()).thenReturn(TaskState.SUSPENDED); - Mockito.when(mockTask.getActivatorName()).thenReturn(SYSTEM_USER_NAME); - Mockito.when(mockTask.getWorkerUserName()).thenReturn(SYSTEM_USER_NAME); - Mockito.when(mockTask.getStartTimestamp()).thenReturn(new Date()); - Mockito.when(mockTask.customFields()).thenReturn(customFields); - Mockito.when(mockTask.customFields().stringField(AdditionalProperty.ADHOC_EXPRESS_TASK.toString())).thenReturn(stringField); - return Arrays.asList(mockTask); - } - - private List createINotes() { - INote mockNote = Mockito.mock(INote.class); - Mockito.when(mockNote.getId()).thenReturn(Long.valueOf(3)); - Mockito.when(mockNote.getMessage()).thenReturn("Sample message"); - Mockito.when(mockNote.getCreationTimestamp()).thenReturn(oneHourFromNow().getTime()); - - IUser mockUser = Mockito.mock(IUser.class); - Mockito.when(mockUser.getDisplayName()).thenReturn("demo"); - Mockito.when(mockNote.getWritter()).thenReturn(mockUser); - return Arrays.asList(mockNote); - } - - private List createTechnicalINotes() { - INote mockNote = Mockito.mock(INote.class); - Mockito.when(mockNote.getId()).thenReturn(Long.valueOf(3)); - Mockito.when(mockNote.getMessage()).thenReturn("Sample message"); - Mockito.when(mockNote.getCreationTimestamp()).thenReturn(oneHourFromNow().getTime()); - - IUser mockUser = Mockito.mock(IUser.class); - Mockito.when(mockUser.getDisplayName()).thenReturn(SYSTEM_USER_NAME); - Mockito.when(mockNote.getWritterName()).thenReturn(SYSTEM_USER_NAME); - Mockito.when(mockNote.getWritter()).thenReturn(mockUser); - return Arrays.asList(mockNote); - } - - private Calendar oneHourFromNow() { - Calendar oneHourFromNow = Calendar.getInstance(); - oneHourFromNow.add(Calendar.HOUR, 1); - return oneHourFromNow; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ConfigurationJsonUtil.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ConfigurationJsonUtil.java deleted file mode 100644 index ee85b3497e5..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ConfigurationJsonUtil.java +++ /dev/null @@ -1,41 +0,0 @@ -package ch.ivy.addon.portalkit.util; - -import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.apache.commons.io.FileUtils; - -import portal.guitest.common.FileHelper; -import portal.guitest.common.PortalGUITestException; -import portal.guitest.common.UrlHelpers; -import portal.guitest.common.Variable; -import vn.wawa.guitest.base.client.Browser; - -public class ConfigurationJsonUtil { - - public static void updateJSONSetting(String fileConfig, Variable variableName) throws IOException { - String customCaseDetais = FileHelper.getAbsolutePathToTestFile(fileConfig); - Path path = Paths.get(customCaseDetais); - String jsonContent = FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8); - updateGlobalVariable(variableName.getKey(), jsonContent); - } - - public static void updateGlobalVariable(String variableName, String variableValue) { - String encodeVariableName = URLEncoder.encode(variableName, StandardCharsets.UTF_8); - String encodeVariableValue = URLEncoder.encode(variableValue, StandardCharsets.UTF_8); - String updateGlobalVariableLink = "portalKitTestHelper/1749B87B8C1B77BE/updateGlobalVariable.ivp?variableName=%s&variableValue=%s"; - redirectToRelativeLink(String.format(updateGlobalVariableLink, encodeVariableName, encodeVariableValue)); - } - - public static void redirectToRelativeLink(String relativeProcessStartUrl) { - Browser browser = Browser.getBrowser(); - try { - browser.goHome(UrlHelpers.generateAbsoluteProcessStartLink(relativeProcessStartUrl)); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DateTimeFormatterTest.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DateTimeFormatterTest.java deleted file mode 100644 index de793d4ff0a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DateTimeFormatterTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package ch.ivy.addon.portalkit.util; - -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import ch.ivy.addon.portalkit.service.CmsDateTimeUnitService; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({CmsDateTimeUnitService.class, DateTimeFormatterUtils.class}) -public class DateTimeFormatterTest { - - private static final String YEAR = "year"; - private static final String DAY = "day"; - private static final String DAYS = "days"; - private static final String HOUR = "hour"; - private static final String HOURS = "hours"; - private static final String MINUTE = "minute"; - private static final String MINUTES = "minutes"; - private static final String SPACE = " "; - private static final String DASH_SPACE = " - "; - - @Before - public void init() throws Exception { - mockStatic(CmsDateTimeUnitService.class); - when(CmsDateTimeUnitService.getCmsYearUnit(1)).thenReturn(YEAR); - when(CmsDateTimeUnitService.getCmsDayUnit(0)).thenReturn(DAY); - when(CmsDateTimeUnitService.getCmsDayUnit(1)).thenReturn(DAY); - when(CmsDateTimeUnitService.getCmsDayUnit(10)).thenReturn(DAYS); - when(CmsDateTimeUnitService.getCmsHourUnit(0)).thenReturn(HOUR); - when(CmsDateTimeUnitService.getCmsHourUnit(1)).thenReturn(HOUR); - when(CmsDateTimeUnitService.getCmsHourUnit(6)).thenReturn(HOURS); - when(CmsDateTimeUnitService.getCmsMinuteUnit(0)).thenReturn(MINUTE); - when(CmsDateTimeUnitService.getCmsMinuteUnit(3)).thenReturn(MINUTES); - when(CmsDateTimeUnitService.getCmsMinuteUnit(10)).thenReturn(MINUTES); - } - - @Test - public void testFormatToShortTimeStringWithValueNotEqualOneMinute() { - Number actualSeconds = 59; - String actual = DateTimeFormatterUtils.formatToShortTimeString(actualSeconds); - String expectedString = getExpectedDateTimeString(0, 0, 0); - Assert.assertTrue(actual.equals(expectedString)); - } - - @Test - public void testFormatToShortTimeStringWithValueNotEqualOneHourAndGreaterThanOneMinute() { - Number seconds = 200; - String actual = DateTimeFormatterUtils.formatToShortTimeString(seconds); - String expectedString = getExpectedDateTimeString(0, 0, 3); - Assert.assertTrue(actual.equals(expectedString)); - } - - @Test - public void testFormatToShortTimeStringWithValueNotEqualOneDayAndGreaterThanOneHour() { - Number seconds = 4200; - String actual = DateTimeFormatterUtils.formatToShortTimeString(seconds); - String expectedString = getExpectedDateTimeString(0, 1, 10); - Assert.assertTrue(actual.equals(expectedString)); - } - - @Test - public void testFormatToShortTimeStringWithThirtyHours() { - Number seconds = 108000; - String actual = DateTimeFormatterUtils.formatToShortTimeString(seconds); - String expectedString = getExpectedDateTimeString(1, 6, 0); - Assert.assertTrue(actual.equals(expectedString)); - } - - private String getExpectedDateTimeString(int days, int hours, int minutes) { - String expectedString = ""; - if (days > 0) { - expectedString = days + SPACE + CmsDateTimeUnitService.getCmsDayUnit(days); - } else if (hours > 0) { - expectedString = hours + SPACE + CmsDateTimeUnitService.getCmsHourUnit(hours); - } else { - expectedString = minutes + SPACE + CmsDateTimeUnitService.getCmsMinuteUnit(minutes); - } - return expectedString; - } - - @Test - public void testFormatToShortTimeStringWithValueGreaterThanOneYear() { - Number seconds = 32400000; - String actual = DateTimeFormatterUtils.formatToShortTimeString(seconds); - String expectedYearsString = getExpectedYearsString(1, 10); - Assert.assertTrue(actual.equals(expectedYearsString)); - } - - @Test - public void testFormatToShortTimeStringWithValueEqualOneYear() { - Number seconds = 31536000; - String actual = DateTimeFormatterUtils.formatToShortTimeString(seconds); - String expectedYearsString = getExpectedYearsString(1, 0); - Assert.assertTrue(actual.equals(expectedYearsString)); - } - - private String getExpectedYearsString(int years, int days) { - String expectedYearsString = ""; - if (years > 0) { - expectedYearsString = years + SPACE + CmsDateTimeUnitService.getCmsYearUnit(years); - if (days > 0) { - expectedYearsString += DASH_SPACE + days + SPACE + CmsDateTimeUnitService.getCmsDayUnit(days); - } - } - return expectedYearsString; - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DatesTest.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DatesTest.java deleted file mode 100644 index 9408c949e21..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DatesTest.java +++ /dev/null @@ -1,159 +0,0 @@ -package ch.ivy.addon.portalkit.util; - -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.time.LocalDate; -import java.util.Calendar; -import java.util.Date; - -import org.apache.commons.lang3.time.DateUtils; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - - -@PrepareForTest({LocalDate.class, Dates.class}) -@RunWith(PowerMockRunner.class) -public class DatesTest { - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase1() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 11); - Date startDate2 = newDateInstance(2015, 11, 11); - Date endDate2 = newDateInstance(2015, 11, 11); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertTrue(isOverlapped); - } - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase2() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 11); - Date startDate2 = newDateInstance(2015, 11, 11); - Date endDate2 = newDateInstance(2015, 11, 15); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertTrue(isOverlapped); - } - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase3() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 11); - Date startDate2 = newDateInstance(2015, 11, 9); - Date endDate2 = newDateInstance(2015, 11, 11); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertTrue(isOverlapped); - } - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase4() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 15); - Date startDate2 = newDateInstance(2015, 11, 12); - Date endDate2 = newDateInstance(2015, 11, 14); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertTrue(isOverlapped); - } - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase5() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 15); - Date startDate2 = newDateInstance(2015, 11, 19); - Date endDate2 = newDateInstance(2015, 11, 21); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertFalse(isOverlapped); - } - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase6() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 11); - Date startDate2 = newDateInstance(2015, 10, 11); - Date endDate2 = newDateInstance(2015, 10, 30); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertFalse(isOverlapped); - } - - @Test - public void testIsTwoPeriodsOfDateOverlappedCase7() { - Date startDate1 = newDateInstance(2015, 11, 11); - Date endDate1 = newDateInstance(2015, 11, 11); - Date startDate2 = newDateInstance(2014, 11, 11); - Date endDate2 = newDateInstance(2014, 11, 11); - boolean isOverlapped = Dates.isTwoPeriodsOfDateOverlapped(startDate1, endDate1, startDate2, endDate2); - Assert.assertFalse(isOverlapped); - } - - private Date newDateInstance(int year, int month, int dayOfMonth) { - Calendar calendar = new Calendar.Builder().set(Calendar.YEAR, year).set(Calendar.MONTH, month) - .set(Calendar.DAY_OF_MONTH, dayOfMonth).build(); - return calendar.getTime(); - } - - private Date newDateInstance(int year, int month, int dayOfMonth, int hour, int minute, int second) { - Calendar calendar = new Calendar.Builder().set(Calendar.YEAR, year).set(Calendar.MONTH, month) - .set(Calendar.DAY_OF_MONTH, dayOfMonth).set(Calendar.HOUR, hour).set(Calendar.MINUTE, minute).set(Calendar.SECOND, second).set(Calendar.MILLISECOND, 000).build(); - return calendar.getTime(); - } - - @Test - public void testGetModayOfLastWeek() { - //today is Mar 23rd, 2018 - LocalDate today = LocalDate.of(2018, 3, 23); - mockStatic(LocalDate.class); - when(LocalDate.now()).thenReturn(today); - Date mondayOfLastWeek = Dates.getMondayOfLastWeek(); - //expected last week monday is Mar 12th, 2018 - Assert.assertTrue(DateUtils.isSameDay(newDateInstance(2018, 2, 12), mondayOfLastWeek)); - } - - @Test - public void testGetSundayOfLastWeek() { - //today is Mar 23rd, 2018 - LocalDate today = LocalDate.of(2018, 3, 23); - mockStatic(LocalDate.class); - when(LocalDate.now()).thenReturn(today); - Date sundayOfLastWeek = Dates.getSundayOfLastWeek(); - //expected last week Sunday is Mar 18th, 2018 - Assert.assertTrue(DateUtils.isSameDay(sundayOfLastWeek, newDateInstance(2018, 2, 18, 23, 59, 59))); - } - - @Test - public void testFirstDayOfLastMonth() { - //today is Mar 23rd, 2018 - LocalDate today = LocalDate.of(2018, 3, 23); - mockStatic(LocalDate.class); - when(LocalDate.now()).thenReturn(today); - Date firstDayOfLastMonth = Dates.getFirstDayOfLastMonth(); - //expected first day of last month Feb 1st, 2018 - Assert.assertTrue(DateUtils.isSameDay(firstDayOfLastMonth, newDateInstance(2018, 1, 1, 23, 59, 59))); - } - - @Test - public void testLastDayOfLastMonth() { - //today is Mar 23rd, 2018 - LocalDate today = LocalDate.of(2018, 3, 23); - mockStatic(LocalDate.class); - when(LocalDate.now()).thenReturn(today); - Date lastDayOfLastMonth = Dates.getLastDayOfLastMonth(); - //expected last day of last month is Feb 28th, 2018 - Assert.assertTrue(DateUtils.isSameDay(lastDayOfLastMonth, newDateInstance(2018, 1, 28, 23, 59, 59))); - } - - @Test - public void testFirstDayOfLast6Month() { - //today is Mar 23rd, 2018 - LocalDate today = LocalDate.of(2018, 3, 23); - mockStatic(LocalDate.class); - when(LocalDate.now()).thenReturn(today); - Date lastDayOfLastMonth = Dates.getFirstDayOfLast6Month(); - //expected last day of last month is Oct 1st, 2017 - Assert.assertTrue(DateUtils.isSameDay(lastDayOfLastMonth, newDateInstance(2017, 9, 1))); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DisplayNameConverterTest.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DisplayNameConverterTest.java deleted file mode 100644 index 5ed98dc28f5..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/DisplayNameConverterTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package ch.ivy.addon.portalkit.util; - -import static org.junit.Assert.assertEquals; - -import java.util.Locale; - -import org.junit.Test; - -public class DisplayNameConverterTest { - - @Test - public void testGetDisplayNameAsMapWhenHaveNoDisplayName() { - DisplayNameConvertor displayNameConvertor = new DisplayNameConvertor(); - assertEquals(displayNameConvertor.getDisplayNameAsMap().size(), 0); - } - - @Test - public void testGetDisplayNameAsMapAfterAddingDisplayName() { - DisplayNameConvertor displayNameConvertor = new DisplayNameConvertor(); - String appName ="InternalSupport"; - Locale locale = new Locale("en"); - displayNameConvertor.add(locale, appName); - assertEquals(displayNameConvertor.getDisplayNameAsMap().size(), 1); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotMargin.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotMargin.java deleted file mode 100644 index 87edf5a807b..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotMargin.java +++ /dev/null @@ -1,76 +0,0 @@ -package ch.ivy.addon.portalkit.util; - -public class ScreenshotMargin { - private int marginTop; - private int marginRight; - private int marginBottom; - private int marginLeft; - - /** - * Generate a margin option with order top, right, bottom, left - * - * @param marginTop - * @param marginRight - * @param marginBottom - * @param marginLeft - */ - public ScreenshotMargin(int marginTop, int marginRight, int marginBottom, int marginLeft) { - this.marginTop = marginTop; - this.marginRight = marginRight; - this.marginBottom = marginBottom; - this.marginLeft = marginLeft; - } - - /** - * Generate a margin option - * - * @param margin - */ - public ScreenshotMargin(int margin) { - this.marginTop = margin; - this.marginRight = margin; - this.marginBottom = margin; - this.marginLeft = margin; - } - - public ScreenshotMargin(int topBottom, int leftRight) { - this.marginTop = topBottom; - this.marginRight = leftRight; - this.marginBottom = topBottom; - this.marginLeft = leftRight; - } - - public int getMarginTop() { - return marginTop; - } - - public void setMarginTop(int marginTop) { - this.marginTop = marginTop; - } - - public int getMarginRight() { - return marginRight; - } - - public void setMarginRight(int marginRight) { - this.marginRight = marginRight; - } - - public int getMarginBottom() { - return marginBottom; - } - - public void setMarginBottom(int marginBottom) { - this.marginBottom = marginBottom; - } - - public int getMarginLeft() { - return marginLeft; - } - - public void setMarginLeft(int marginLeft) { - this.marginLeft = marginLeft; - } - - -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotUtil.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotUtil.java deleted file mode 100644 index 490bcbef28f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portalkit/util/ScreenshotUtil.java +++ /dev/null @@ -1,258 +0,0 @@ -package ch.ivy.addon.portalkit.util; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -import javax.annotation.PostConstruct; -import javax.imageio.ImageIO; - -import org.apache.commons.io.FileUtils; -import org.openqa.selenium.Dimension; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.OutputType; -import org.openqa.selenium.TakesScreenshot; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; -import vn.wawa.guitest.base.client.Browser; - -public class ScreenshotUtil { - private static final String SCREENSHOT_EXTENSION = ".png"; - private static final String SCREENSHOT_FOLDER = "target" + File.separator + "screenshots" + File.separator; - public static final String LOGIN_FOLDER = "/login/"; - public static final String FORGOT_PASSWORD = "/forgot-password/"; - public static final String DASHBOARD_FOLDER = "/dashboard/"; - public static final String NEW_DASHBOARD_FOLDER = "/new-dashboard/"; - public static final String EXPRESS_FOLDER = "/express/"; - public static final String EXPRESS_MANAGEMENT_FOLDER = "/express-management/"; - public static final String PROCESSES_WIDGET_FOLDER = "/process/"; - public static final String PROCESSES_INFORMATION_WIDGET_FOLDER = "/process/information/"; - public static final String PROCESSES_PROCESS_IMAGE_FOLDER = "/process-image/customization/"; - public static final String TASK_WIDGET_FOLDER = "/task/"; - public static final String TASK_WIDGET_CUSTOMIZATION_FOLDER = "/task/customization/"; - public static final String TASK_DETAIL_FOLDER = "/task-detail/"; - public static final String TASK_DETAIL_CUSTOMIZATION_FOLDER = "/task-detail/customization/"; - public static final String CASE_WIDGET_FOLDER = "/case/"; - public static final String CASE_WIDGET_CUSTOMIZATION_FOLDER = "/case/customization/"; - public static final String CASE_DETAIL_FOLDER = "/case-detail/"; - public static final String CASE_DETAIL_CUSTOMIZATION_FOLDER = "/case-detail/customization/"; - public static final String STATISTIC_WIDGET_FOLDER = "/statistic/"; - public static final String TASK_ANALYSIS_FOLDER = "/statistic/task-analysis/"; - public static final String SEARCH_FOLDER = "/search/"; - public static final String SETTINGS_FOLDER = "/settings/"; - public static final String MY_PROFILE_FOLDER = "/my-profile/"; - public static final String CHAT_FOLDER = "/chat/"; - public static final String TASK_TEMPLATE_FOLDER = "/task-template/"; - public static final String COMPONENTS_FOLDER = "/components/"; - public static final String DEMO_FOLDER = "/demo-processes/"; - public static final String LAYOUT_FOLDER = "/layout-template/"; - public static final String ERROR_HANDLING_FOLDER = "/error-handling/"; - public static final String DASHBOARD_CONFIGURATION_FOLDER = "/dashboard-configuration/"; - - @PostConstruct - public void initFolder() { - new File(SCREENSHOT_FOLDER).mkdirs(); - } - - public static void capturePageScreenshot(String screenshotName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - public static void captureElementScreenshot(WebElement element, String screenshotName) throws IOException { - File screenshot = element.getScreenshotAs(OutputType.FILE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - public static void captureElementWithMarginOptionScreenshot(WebElement element, String screenshotName, ScreenshotMargin screenshotMargin) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - addMarginForImage(element, screenshot, screenshotMargin); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - private static File addMarginForImage(WebElement element, File fileScreenShot, ScreenshotMargin screenshotMargin) throws IOException { - BufferedImage original = ImageIO.read(fileScreenShot); - int coordinateX = element.getLocation().getX() - screenshotMargin.getMarginLeft(); - int coordinateY = element.getLocation().getY() - screenshotMargin.getMarginTop(); - int width = element.getSize().getWidth() + screenshotMargin.getMarginRight() + screenshotMargin.getMarginLeft(); - int height = element.getSize().getHeight() + screenshotMargin.getMarginBottom() + screenshotMargin.getMarginTop(); - - if (coordinateX < 0) { - coordinateX = 0; - } else if (coordinateX > original.getWidth()) { - coordinateX = original.getWidth(); - } - - if (coordinateY < 0) { - coordinateY = original.getMinY(); - } else if (coordinateY > original.getHeight()) { - coordinateY = original.getHeight(); - } - - if (width > original.getWidth() || width + coordinateX > original.getWidth()) { - width = original.getWidth() - coordinateX; - } - - if (height > original.getHeight() || height + coordinateY > original.getHeight()) { - height = original.getHeight() - coordinateY; - } - - BufferedImage screenshot = original.getSubimage( - coordinateX, - coordinateY, - width, - height); - ImageIO.write(screenshot, "png", fileScreenShot); - return fileScreenShot; - } - - public static void resizeBrowserAndCaptureWholeScreen(String screenshotName, Dimension size) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - Dimension oldSize = driver.manage().window().getSize(); - resizeBrowser(size); - executeDecorateJs(driver); - capturePageScreenshot(screenshotName); - resizeBrowser(oldSize); - } - - public static void resizeBrowserAndCaptureHalfRightScreen(String screenshotName, Dimension size) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - Dimension oldSize = driver.manage().window().getSize(); - resizeBrowser(size); - executeDecorateJs(driver); - captureHalfRightPageScreenShot(screenshotName); - resizeBrowser(oldSize); - } - - public static void captureHalfRightPageScreenShot(String screenshotName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - getHalfOfPageScreenshot(screenshot, ScreenCoordinate.RIGHT_SIDE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - private static File getHalfOfPageScreenshot(File screenshot, ScreenCoordinate coordinateSide) throws IOException { - BufferedImage original = ImageIO.read(screenshot); - int coordinateX = 0; - int coordinateY = 0; - int width = original.getWidth(); - int height = original.getHeight(); - switch (coordinateSide) { - case TOP_SIDE: - height = original.getHeight()/2; - break; - case RIGHT_SIDE: - coordinateX = original.getWidth()/2; - if (coordinateX + width > original.getWidth()) { - width = original.getWidth() - coordinateX; - } - break; - case BOTTOM_SIDE: - break; - case LEFT_SIDE: - width = original.getWidth()/2; - break; - case TOP_RIGHT: - coordinateX = original.getWidth()/2; - if (coordinateX + width > original.getWidth()) { - width = original.getWidth() - coordinateX; - } - height = original.getHeight()/2; - break; - case CENTER_TOP_SIDE: - coordinateX = original.getWidth()/4; - coordinateY = 0; - width = original.getWidth()/2; - height = original.getHeight()/2; - break; - default: - break; - } - BufferedImage halfOfScreenshot = original.getSubimage( - coordinateX, - coordinateY, - width, - height); - ImageIO.write(halfOfScreenshot, "png", screenshot); - return screenshot; - } - - public static void captureHalfLeftPageScreenShot(String screenshotName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - getHalfOfPageScreenshot(screenshot, ScreenCoordinate.LEFT_SIDE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - public static void resizeBrowser(Dimension size) { - Browser.getBrowser().getDriver().manage().window().setSize(size); - WaitHelper.assertTrueWithWait(() -> { - Dimension currentSize = Browser.getBrowser().getDriver().manage().window().getSize(); - return currentSize.getWidth() == size.getWidth() - && currentSize.getHeight() == size.getHeight(); - }); - } - - public static void maximizeBrowser() { - Browser.getBrowser().getDriver().manage().window().maximize(); - Sleeper.sleep(300); // Wait for window resized successfully - } - - private static void executeDecorateJs(WebDriver driver) { - JavascriptExecutor jse = (JavascriptExecutor) driver; - jse.executeScript("scroll(0,0);"); - Sleeper.sleep(200); // Wait for JS executed successfully - } - - public static void captureHalfCenterTopPageScreenShot(String screenshotName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - getHalfOfPageScreenshot(screenshot, ScreenCoordinate.CENTER_TOP_SIDE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - public static void captureHalfTopRightPageScreenShot(String screenshotName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - getHalfOfPageScreenshot(screenshot, ScreenCoordinate.TOP_RIGHT); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - public static void captureHalfTopPageScreenShot(String screenshotName, Dimension size) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - resizeBrowser(size); - - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - getHalfOfPageScreenshot(screenshot, ScreenCoordinate.TOP_SIDE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - public static void captureHalfTopPageScreenShot(String screenshotName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - getHalfOfPageScreenshot(screenshot, ScreenCoordinate.TOP_SIDE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + screenshotName + SCREENSHOT_EXTENSION); - FileUtils.copyFile(screenshot, fileScreenShot); - } - - public enum ScreenCoordinate { - LEFT_SIDE, RIGHT_SIDE, TOP_SIDE, BOTTOM_SIDE, CENTER_TOP_SIDE, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT; - } - - public static boolean isDOMStatusComplete() { - return ((JavascriptExecutor) Browser.getBrowser().getDriver()) - .executeScript("return document.readyState").equals("complete"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/CaseWidgetBeanTest.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/CaseWidgetBeanTest.java deleted file mode 100644 index 874beb1bcff..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/CaseWidgetBeanTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package ch.ivy.addon.portaltemplate.generic.bean; - -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import ch.ivy.addon.portalkit.bean.CaseWidgetBean; -import ch.ivy.addon.portalkit.enums.AdditionalProperty; -import ch.ivy.addon.portalkit.util.PermissionUtils; -import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.custom.field.ICustomFields; -import ch.ivyteam.ivy.workflow.custom.field.ICustomStringField; - -@RunWith(PowerMockRunner.class) -public class CaseWidgetBeanTest { - private static final String CUSTOMIZATION_ADDITIONAL_CASE_DETAILS_PAGE = "CustomizationAdditionalCaseDetailsPage"; - - CaseWidgetBean caseWidgetBean; - - @Mock - private FacesContext facesContext; - @Mock - private ExternalContext externalContext; - - @Before - @PrepareForTest(PermissionUtils.class) - public void init() { - PowerMockito.mockStatic(PermissionUtils.class); - caseWidgetBean = new CaseWidgetBean(); - } - - @Test - @PrepareForTest({CaseWidgetBean.class, PermissionUtils.class, FacesContext.class}) - public void testGetAdditionalCaseDetailsPageUriWithCustomization() throws Exception { - mockCustomFieldForCaseDetailsPage(CUSTOMIZATION_ADDITIONAL_CASE_DETAILS_PAGE); - PowerMockito.mockStatic(FacesContext.class); - - PowerMockito.when(FacesContext.getCurrentInstance()).thenReturn(facesContext); - PowerMockito.when(facesContext.getExternalContext()) - .thenReturn(externalContext); - PowerMockito.when(externalContext.getApplicationContextPath()).thenReturn(""); - } - - private ICase mockCustomFieldForCaseDetailsPage(String detailsPage) { - ICase iCase = PowerMockito.mock(ICase.class); - ICustomFields iCustomFields = PowerMockito.mock(ICustomFields.class); - ICustomStringField iCustomStringField = PowerMockito.mock(ICustomStringField.class); - PowerMockito.when(iCase.customFields()).thenReturn(iCustomFields); - PowerMockito.when(iCustomFields.textField(AdditionalProperty.CUSTOMIZATION_ADDITIONAL_CASE_DETAILS_PAGE.toString())).thenReturn(iCustomStringField); - PowerMockito.when(iCustomStringField.getOrNull()).thenReturn(detailsPage); - return iCase; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/UserMenuBeanTest.java b/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/UserMenuBeanTest.java deleted file mode 100644 index b9454b947e7..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/ch/ivy/addon/portaltemplate/generic/bean/UserMenuBeanTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package ch.ivy.addon.portaltemplate.generic.bean; - -import static ch.ivy.addon.portalkit.enums.GlobalVariable.HIDE_LOGOUT_BUTTON; -import static ch.ivy.addon.portalkit.enums.GlobalVariable.LOGGED_IN_USER_FORMAT; -import static org.junit.Assert.assertEquals; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.verifyNew; -import static org.powermock.api.mockito.PowerMockito.when; -import static org.powermock.api.mockito.PowerMockito.whenNew; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import ch.ivy.addon.portal.generic.bean.UserMenuBean; -import ch.ivy.addon.portalkit.service.GlobalSettingService; -import ch.ivyteam.ivy.cm.IContentManagementSystem; -import ch.ivyteam.ivy.environment.Ivy; -import ch.ivyteam.ivy.security.IUser; -import ch.ivyteam.ivy.workflow.IWorkflowSession; - -@RunWith(PowerMockRunner.class) -public class UserMenuBeanTest { - - private UserMenuBean userMenuBean; - private GlobalSettingService globalSettingService; - String testUsername = "test"; - - - @Before - public void init() throws Exception { - userMenuBean = new UserMenuBean(); - - mockStatic(Ivy.class); - IWorkflowSession session = mock(IWorkflowSession.class); - IContentManagementSystem icms = mock(IContentManagementSystem.class); - IUser user = mock(IUser.class); - when(Ivy.session()).thenReturn(session); - when(session.getSessionUserName()).thenReturn(testUsername); - when(session.getSessionUser()).thenReturn(user); - when(user.getFullName()).thenReturn(testUsername); - when(Ivy.cms()).thenReturn(icms); - - globalSettingService = mock(GlobalSettingService.class); - whenNew(GlobalSettingService.class).withNoArguments().thenReturn(globalSettingService); - when(globalSettingService.findGlobalSettingValue(HIDE_LOGOUT_BUTTON)).thenReturn("true"); - when(globalSettingService.findGlobalSettingValue(LOGGED_IN_USER_FORMAT)).thenReturn("USERNAME"); - - this.userMenuBean.init(); - } - - @Test - @PrepareForTest({ Ivy.class, UserMenuBean.class }) - public void testGetUserName() { - assertEquals(userMenuBean.getLoggedInUser(), testUsername); - } - - - @Test - @PrepareForTest({ Ivy.class, UserMenuBean.class }) - public void testIsHiddenLogout() throws Exception { - assertEquals(Boolean.TRUE, userMenuBean.isHiddenLogout()); - verifyNew(GlobalSettingService.class).withNoArguments(); - Mockito.verify(globalSettingService).findGlobalSettingValue(HIDE_LOGOUT_BUTTON); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/bean/ExpressResponsible.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/bean/ExpressResponsible.java deleted file mode 100644 index 7edbc86e01d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/bean/ExpressResponsible.java +++ /dev/null @@ -1,21 +0,0 @@ -package portal.guitest.bean; - -public class ExpressResponsible { - - private String responsibleName; - private boolean isGroup; - - public ExpressResponsible(String responsibleName, boolean isGroup) { - super(); - this.responsibleName = responsibleName; - this.isGroup = isGroup; - } - - public String getResponsibleName() { - return responsibleName; - } - - public boolean isGroup() { - return isGroup; - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/BaseTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/BaseTest.java deleted file mode 100644 index 457bfdbeba9..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/BaseTest.java +++ /dev/null @@ -1,319 +0,0 @@ -package portal.guitest.common; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.concurrent.TimeUnit; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; -import org.openqa.selenium.JavascriptExecutor; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import ch.ivy.addon.portalkit.enums.PortalPermission; -import portal.guitest.page.NewDashboardPage; -import vn.wawa.guitest.base.client.Browser; -import vn.wawa.guitest.base.enums.BrowserType; - -/** - * A base test that other tests extend it. It will test on browser IE by default. It provides feature to take screenshot - * of failed tests and utility methods. - * - */ -public class BaseTest { - private Browser browser; - - private String designerLogoutUrl = "http://localhost:8081/designer/logout"; - private final static String LOGIN_URL_PATTERN = "portalKitTestHelper/1636734E13CEC872/login.ivp?username=%s&password=%s"; - private final static String LOGOUT_URL = "/PortalKitTestHelper/1636734E13CEC872/logout.ivp"; - private BrowserType browserType; - - public BaseTest() { - String vmArgPath = System.getProperty("browserType"); - if (vmArgPath != null) { - browserType = BrowserType.valueOf(vmArgPath); - } else { - browserType = BrowserType.valueOf(PropertyLoader.getBrowserType()); - } - } - - public Browser getBrowser() { - return browser; - } - - public void setBrowser(Browser browser) { - this.browser = browser; - } - - protected String createTestingTasksUrl = "portal-developer-examples/162511D2577DBA88/CategoriedLeaveRequest.ivp"; - protected String createCaseWithTechnicalCaseUrl = "InternalSupport/15B1EA24CCF377E8/OrderPizza.ivp"; - protected String create12CasesWithCategoryUrl = "internalSupport/15C7B30FB93C827E/create12CasesWithCategory.ivp"; - protected String businessCaseUrl = "internalSupport/15B1EA24CCF377E8/updateCheckInTime.ivp"; - protected String hideCaseUrl = "portal-developer-examples/16583F0F73864543/createHiddenTechnicalCase.ivp"; - protected String createTestingCaseMapUrl = "internalSupport/764871e4-cf70-401f-83fb-9e99fa897fc4.icm"; - protected String createTestingCaseUrlForCustomizationAdditionalCaseDetails = "portal-components-examples/176465FBFE257CF3/createInvestmentRequest.ivp"; - protected String createTaskWithIframe = "portal-developer-examples/16E5DB746865BCEC/CreateInvestment.ivp"; - protected String createTestingCaseUrlForDefaultAdditionalCaseDetails = "internalSupport/14B2FC03D2E87141/DefaultAdditionalCaseDetails.ivp"; - protected String createTestingCaseContainOneTask = "internalSupport/14B2FC03D2E87141/CreateSupportTicket.ivp"; - protected String createTaskWithNotExistedActivatorUrl = "internalSupport/14B2FC03D2E87141/createTaskWithNotExistedActivator.ivp"; - protected String expressStartLink = "axonivy-express/15798655494F25E1/AxonIvyExpressWF.ivp"; - protected String cleanupDataLink = "portalKitTestHelper/1511A66AF619A768/cleanData.ivp"; - protected String createAlphaCompanyUrl = "portal-components-examples/1818977D467E3129/createAlphaCompany.ivp"; - protected String viewAlphaCompanyProcessHistoryUrl = "portal-components-examples/1818977D467E3129/viewProcessHistoryOfAlphaCompany.ivp"; - protected String createBetaCompanyUrl = "portal-components-examples/1818977D467E3129/createBetaCompany.ivp"; - protected String viewBetaCompanyProcessHistoryInDialogUrl = "portal-components-examples/1818977D467E3129/viewProcessHistoryOfBetaCompany.ivp"; - protected String createNewPaymentUrl = "portal-developer-examples/162511D2577DBA88/createNewPayment.ivp"; - protected String simplePaymentUrl = "portal-developer-examples/162511D2577DBA88/simplePayment.ivp"; - protected String complexPaymentUrl = "portal-developer-examples/162511D2577DBA88/complexPayment.ivp"; - protected String documentTableComponentUrl = "portal-components-examples/1818938E7EBC9329/showCustomizedDocumentTableExample.ivp"; - protected String cleanUpAbsencesAndSubstituesLink = "portalKitTestHelper/1511A66AF619A768/cleanAbsencesAndSubstitues.ivp"; - protected String createCasesForCaseListCustomization = "portal-developer-examples/162511D2577DBA88/createCasesForCaseListCustomization.ivp"; - protected String processChainShowcaseUrl = "portal-components-examples/181897243F2BFDD3/showProcessChainExamples.ivp"; - protected String userSelectionComponentShowcaseUrl = "portal-components-examples/18189AF10B521DF4/showUserSelectionExamples.ivp"; - protected String roleSelectionComponentShowcaseUrl = "portal-components-examples/181899823E886ABB/showRoleSelectionExamples.ivp"; - protected String startUserExampleProcess = "portal-user-examples/17236DB1D3DA14C0/userExampleGuide.ivp"; - protected String userIsOwnerUrl = "internalSupport/16A68510A341BE6E/userIsOwner.ivp"; - protected String showTaskNoteHistoryUrl = "portal/1549F58C18A6C562/showTaskNoteHistory.ivp?uuid=%s"; - protected String showCaseNoteHistoryUrl = "portal/1549F58C18A6C562/showCaseNoteHistory.ivp?uuid=%s"; - protected String createTaskWithSystemState = "portalKitTestHelper/153CACC26D0D4C3D/createTaskWithSystemState.ivp"; - protected String createTechnicalStateUrl = "portal-developer-examples/162511D2577DBA88/createTechnicalStateTasks.ivp"; - protected String portalKitTestHelperPasswordResetUrl = "portalKitTestHelper/176463FD4BBF6C93/PasswordReset.ivp"; - protected String portalPasswordResetUrl = "portal/1549F58C18A6C562/PasswordResetPage.ivp?token=%s&username=%s"; - protected String cleanSessionCacheUrl = "portalKitTestHelper/17208192E0AF4185/cleanSessionCache.ivp"; - protected String showProcessViewerUrl = "portal/1549F58C18A6C562/PortalProcessViewer.ivp?caseId=%s&processKey=%s"; - protected String processViewerPermissionExampleUrl = "portal-developer-examples/183C12775FE2BAB8/start.ivp"; - protected String testProcessViewerPermissionUrl = "portalKitTestHelper/153CACC26D0D4C3D/testProcessViewerPermission.ivp"; - protected String createSampleDashboardUrl = "portalKitTestHelper/17F2050944B46BB0/createSampleDashboard.ivp"; - protected String processViewerExampleInFrameUrl = "portal-components-examples/1821592826979C20/showProcessViewerOfLeaveRequestUsingProcessLink.ivp"; - protected String defaultProcessImageSelectionExampleUrl = "portal-developer-examples/179D499523153784/start.ivp"; - protected String securityMemberNameAndAvatarExampleInFrameUrl = "/portal-components-examples/182A5FCAF7FC6B1A/showSecurityMemberNameAndAvatarExamples.ivp?embedInFrame"; - protected String templateInFrameExampleInFrameUrl = "/portal-developer-examples/162511D2577DBA88/createTaskWithFrameTemplate.ivp?embedInFrame"; - public static final long DEFAULT_TIMEOUT = 15; - - @Rule - public ScreenshotFailedTestRule screenshotTestRule = new ScreenshotFailedTestRule(); - - @Rule - public TestWatcher watchman= new TestWatcher() { - - @Override - protected void starting(Description description) { - super.starting(description); - System.out.println("Starting test: " + description.getMethodName()); - } - - }; - - @Before - /** - * Default setup for each test - * It will clean up all test data and login with account demo - */ - public void setup() { - browser = Browser.getBrowser(); - launchBrowserAndGotoRelativeLink(cleanupDataLink); - } - - /** - * Alternative setup, just login with input account, don't cleanup anything - * @param relativePath - * @param account - */ - public void setupWithAlternativeLinkAndAccount(String relativePath, TestAccount account) { - browser = Browser.getBrowser(); - launchBrowserAndGotoRelativeLink(relativePath); - login(account); - } - - public void launchBrowserAndGotoRelativeLink(String relativeProcessStartLink) { - try { - browser.launch(browserType, UrlHelpers.generateAbsoluteProcessStartLink(relativeProcessStartLink), getDriverPath()); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public void redirectToRelativeLink(String relativeProcessStartUrl) { - try { - browser.goHome(UrlHelpers.generateAbsoluteProcessStartLink(relativeProcessStartUrl)); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public void redirectToRelativeLinkWithEmbedInFrame(String relativeProcessStartUrl) { - try { - browser.goHome(UrlHelpers.generateAbsoluteProcessStartLink(relativeProcessStartUrl) + "?embedInFrame"); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public void launchBrowserAndLogoutInDesigner() { - try { - browser.launch(browserType, designerLogoutUrl, getDriverPath()); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - protected void logoutDesigner() { - try { - browser.goHome(designerLogoutUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public void createTestingTasks() { - redirectToRelativeLink(createTestingTasksUrl); - } - - public void grantTaskReadAllPermissionsToCurrentUser() { - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantTaskReadAllPermissionsToCurrentUser.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - public void grantTaskReadOwnCaseTaskPermissionsToCurrentUser() { - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantTaskReadOwnCaseTaskPermissionsToCurrentUser.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - public void denyReadAllPermissionFromCurrentUser() { - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/denyReadAllPermissionFromCurrentUser.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - public void denyDocumentOfInvolvedCaseWritePemissionFromCurrentUser() { - String denyDocumentOfInvolvedCaseWritePemissionURL = "portalKitTestHelper/14DE09882B540AD5/denyDocumentOfInvolvedCaseWritePemission.ivp"; - redirectToRelativeLink(denyDocumentOfInvolvedCaseWritePemissionURL); - } - - public void grantDocumentOfInvolvedCaseWritePemissionToCurrentUser() { - String grantDocumentOfInvolvedCaseWritePemissionURL = "portalKitTestHelper/14DE09882B540AD5/grantDocumentOfInvolvedCaseWritePemission.ivp"; - redirectToRelativeLink(grantDocumentOfInvolvedCaseWritePemissionURL); - } - - public void grantSpecificPortalPermission(PortalPermission portalPermission) { - String grantSpecificPortalPermissionLink = "portalKitTestHelper/14DE09882B540AD5/grantSpecificPortalPermission.ivp?portalPermission=%s"; - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, portalPermission.getValue())); - } - - public void denySpecificPortalPermission(PortalPermission portalPermission) { - String denySpecificPortalPermissionLink = "portalKitTestHelper/14DE09882B540AD5/denySpecificPortalPermission.ivp?portalPermission=%s"; - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, portalPermission.getValue())); - } - - public void cleanUpGlobalVariables(){ - String cleanUpURL = "portalKitTestHelper/1511A66AF619A768/cleanupGlobalVars.ivp"; - redirectToRelativeLink(cleanUpURL); - } - - public void resetLanguageOfCurrentUser(){ - redirectToRelativeLink("portalKitTestHelper/1511A66AF619A768/resetLanguageOfCurrentUser.ivp"); - } - - public void createThirdPartyApp() { - redirectToRelativeLink("PortalKitTestHelper/153CACC26D0D4C3D/createThirdPartyApp.ivp"); - - } - - public void refreshPage(){ - browser.getDriver().navigate().refresh(); - } - - protected void login(TestAccount testAccount) { - String username; - String password; - try { - username = URLEncoder.encode(testAccount.getUsername(), "UTF-8"); - password = URLEncoder.encode(testAccount.getPassword(), "UTF-8"); - - Awaitility.await().atMost(new Duration(60, TimeUnit.SECONDS)).until(() -> { - try { - redirectToRelativeLink(String.format(LOGIN_URL_PATTERN, username, password)); - return new NewDashboardPage() { - @Override - protected long getTimeOutForLocator() { - return 10L; - } - }.findElementByCssSelector(".user-name").getText().equals(testAccount.getFullName()); - } catch (Exception e) { - System.out.println("*****Login unsuccessfully. Try again if not timeout."); - } - return false; - }); - - } catch (UnsupportedEncodingException e) { - throw new PortalGUITestException(e); - } - } - - protected void logout() { - redirectToRelativeLink(String.format(LOGOUT_URL)); - } - - public static void killBrowsers() { - try { - System.out.println("Kill all open browsers"); - Runtime.getRuntime().exec("taskkill /F /IM iexplore.exe"); - Runtime.getRuntime().exec("taskkill /F /IM firefox.exe"); - Sleeper.sleep(5000); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private String getDriverPath() { - return browserType.getConfiguration().getDriverPath(); - } - - public void updatePortalSetting(String portalSettingName, String portalSettingValue) { - try { - String encodeSettingName = URLEncoder.encode(portalSettingName, "UTF-8"); - String encodeSettingValue = URLEncoder.encode(portalSettingValue, "UTF-8"); - String updatePortalSettingLink = "portalKitTestHelper/17208192E0AF4185/updatePortalSetting.ivp?settingName=%s&settingValue=%s"; - redirectToRelativeLink(String.format(updatePortalSettingLink, encodeSettingName, encodeSettingValue)); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - - public void updateGlobalVariable(String variableName, String variableValue) { - try { - String encodeVariableName = URLEncoder.encode(variableName, "UTF-8"); - String encodeVariableValue = URLEncoder.encode(variableValue, "UTF-8"); - String updateGlobalVariableLink = "portalKitTestHelper/1749B87B8C1B77BE/updateGlobalVariable.ivp?variableName=%s&variableValue=%s"; - redirectToRelativeLink(String.format(updateGlobalVariableLink, encodeVariableName, encodeVariableValue)); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - - public void goToTaskNoteHistoryPage(String uuid) { - redirectToRelativeLink(String.format(showTaskNoteHistoryUrl, uuid)); - } - - public void goToCaseNoteHistoryPage(String uuid) { - redirectToRelativeLink(String.format(showCaseNoteHistoryUrl, uuid)); - } - - - public void executeDecorateJs(String function) { - var jsExecutor = (JavascriptExecutor) getBrowser().getDriver(); - try { - jsExecutor.executeScript(function); - } catch (Exception e) { - // In case `ReferenceError: js function is not defined` then try again - Sleeper.sleep(2000); - jsExecutor.executeScript(function); - } - Sleeper.sleep(200); // Wait for JS executed successfully - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/CaseState.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/CaseState.java deleted file mode 100644 index 2c45d018d75..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/CaseState.java +++ /dev/null @@ -1,17 +0,0 @@ -package portal.guitest.common; - -public enum CaseState { - OPEN, DONE, DESTROYED; - - public static CaseState fromClass(String stateClass) { - switch (stateClass.trim()) { - case "done-case-state": - return DONE; - - case "destroyed-case-state": - return DESTROYED; - default: - return OPEN; - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/DateTimePattern.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/DateTimePattern.java deleted file mode 100644 index 238788eb60f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/DateTimePattern.java +++ /dev/null @@ -1,9 +0,0 @@ -package portal.guitest.common; - -public class DateTimePattern { - - public static final String DATE_PATTERN = "dd/MM/yyyy"; - public static final String DATE_TIME_PATTERN = "dd/MM/yyyy HH:mm"; - public static final String LOCALE_DATE_TIME_PATTERN = "d MMM y HH:mm"; //This pattern is for en_UK locale; - public static final String LOCALE_DATE_PATTERN = "d MMM y"; //This pattern is for en_UK locale; -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/FileHelper.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/FileHelper.java deleted file mode 100644 index e92d4eb713d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/FileHelper.java +++ /dev/null @@ -1,9 +0,0 @@ -package portal.guitest.common; - -public final class FileHelper { - private FileHelper() {} - - public static String getAbsolutePathToTestFile(String fileName) { - return System.getProperty("user.dir") + "\\resources\\testFile\\" + fileName; - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/NavigationHelper.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/NavigationHelper.java deleted file mode 100644 index 88dadeb6db8..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/NavigationHelper.java +++ /dev/null @@ -1,34 +0,0 @@ -package portal.guitest.common; - -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.TaskWidgetPage; -import vn.wawa.guitest.base.client.Browser; - -public class NavigationHelper { - private static final String TASK_LIST_PAGE_URL = "portal/1549F58C18A6C562/DefaultTaskListPage.ivp"; - private static final String CASE_LIST_PAGE_URL = "portal/1549F58C18A6C562/CaseListPage.ivp"; - private static final String PROCESS_LIST_PAGE_URL = "portal/1549F58C18A6C562/DefaultProcessStartListPage.ivp"; - public static void navigateToRelativeLink(String relativeProcessStartUrl) { - try { - Browser.getBrowser().goHome(UrlHelpers.generateAbsoluteProcessStartLink(relativeProcessStartUrl)); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public static TaskWidgetPage navigateToTaskList() { - navigateToRelativeLink(TASK_LIST_PAGE_URL); - return new TaskWidgetPage(); - } - - public static CaseWidgetPage navigateToCaseList() { - navigateToRelativeLink(CASE_LIST_PAGE_URL); - return new CaseWidgetPage(); - } - - public static ProcessWidgetPage navigateToProcessList() { - navigateToRelativeLink(PROCESS_LIST_PAGE_URL); - return new ProcessWidgetPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PortalGUITestException.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PortalGUITestException.java deleted file mode 100644 index 467b37ffc45..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PortalGUITestException.java +++ /dev/null @@ -1,19 +0,0 @@ -package portal.guitest.common; - -public class PortalGUITestException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public PortalGUITestException(String paramString, Throwable paramThrowable) { - super(paramString, paramThrowable); - } - - public PortalGUITestException(String paramString) { - super(paramString); - } - - public PortalGUITestException(Throwable paramThrowable) { - super(paramThrowable); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PropertyLoader.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PropertyLoader.java deleted file mode 100644 index 24cfa4fff7e..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/PropertyLoader.java +++ /dev/null @@ -1,55 +0,0 @@ -package portal.guitest.common; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -public class PropertyLoader { - private static final String SERVER_ADDRESS = "server.address"; - private static final String IVY_ENGINE_PORT = "ivy.engine.port"; - private static final String APPLICATION_NAME = "application.name"; - private static final String BROWSER_TYPE = "browser.type"; - private static final String CONFIG_WINDOWS_SERVER = "resources/config_windows_server.properties"; - private static final String CONFIG_DESIGNER = "resources/config_designer.properties"; - - private static Properties properties; - - static { - loadProperties(); - } - - private static void loadProperties() { - try { - InputStream inputStream = new FileInputStream(getPropertyFileName()); - properties = new Properties(); - properties.load(inputStream); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static String getPropertyFileName() { - if (SystemProperties.isInServerMode()) { - return CONFIG_WINDOWS_SERVER; - } - return CONFIG_DESIGNER; - } - - public static String getIvyEnginePort() { - return properties.getProperty(IVY_ENGINE_PORT); - } - - public static String getServerAddress() { - return properties.getProperty(SERVER_ADDRESS); - } - - public static String getApplicationName() { - return properties.getProperty(APPLICATION_NAME); - } - - public static String getBrowserType() { - return properties.getProperty(BROWSER_TYPE); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotFailedTestRule.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotFailedTestRule.java deleted file mode 100644 index e045285d1cb..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotFailedTestRule.java +++ /dev/null @@ -1,64 +0,0 @@ -package portal.guitest.common; - -import java.io.File; -import java.io.IOException; -import java.util.Date; - -import org.apache.commons.io.FileUtils; -import org.junit.rules.MethodRule; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; -import org.openqa.selenium.OutputType; -import org.openqa.selenium.TakesScreenshot; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebDriverException; - -import vn.wawa.guitest.base.client.Browser; - -public class ScreenshotFailedTestRule implements MethodRule { - private static final String SCREENSHOT_FOLDER = "target" + File.separator + "test" + File.separator + "screenshot" - + File.separator + ""; - - @Override - public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, Object arg2) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - try { - statement.evaluate(); - } catch (Throwable t) { - t.printStackTrace(); - captureScreenshot(frameworkMethod.getName()); - throw t; - } finally { - try { - System.out.println("Before shutdown " + new Date()); - Browser.getBrowser().shutdown(); - System.out.println("After shutdown " + new Date()); - } catch (Exception e) { - System.out.println("Exception " + new Date()); - if (e instanceof WebDriverException) { - System.out.println("ERROR maybe browsers are killed before shutdown"); - } else { - e.printStackTrace(); - captureScreenshot(frameworkMethod.getName() + "-shutdown-error"); - System.out.println("captureScreenshot " + new Date()); - Browser.getBrowser().shutdown(); - System.out.println("shutdown" + new Date()); - } - } - } - } - - public void captureScreenshot(String methodName) throws IOException { - WebDriver driver = Browser.getBrowser().getDriver(); - new File(SCREENSHOT_FOLDER).mkdirs(); - File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - File fileScreenShot = new File(SCREENSHOT_FOLDER + methodName + "_Failed.jpg"); - - FileUtils.copyFile(screenshot, fileScreenShot); - } - }; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotTest.java deleted file mode 100644 index d6af70d6a13..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/ScreenshotTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package portal.guitest.common; - -import static portal.guitest.common.Variable.DISPLAY_MESSAGE_AFTER_FINISH_TASK; - -import org.junit.Before; - -public class ScreenshotTest extends BaseTest { - - @Before - @Override - public void setup() { - killBrowsers(); - super.setup(); - updatePortalSetting(DISPLAY_MESSAGE_AFTER_FINISH_TASK.getKey(), "false"); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Sleeper.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Sleeper.java deleted file mode 100644 index aab3f4b1cac..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Sleeper.java +++ /dev/null @@ -1,11 +0,0 @@ -package portal.guitest.common; - -public final class Sleeper { - public static final void sleep(long milis) { - try { - org.openqa.selenium.support.ui.Sleeper.SYSTEM_SLEEPER.sleep(java.time.Duration.ofMillis(milis)); - } catch (InterruptedException e) { - throw new PortalGUITestException(e); - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/SystemProperties.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/SystemProperties.java deleted file mode 100644 index 4bca97e597a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/SystemProperties.java +++ /dev/null @@ -1,25 +0,0 @@ -package portal.guitest.common; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -public class SystemProperties { - - private static String osName = System.getProperty("os.name").toLowerCase(); - - public static boolean isInServerMode() { - return osName.contains("server"); - } - - public static String getServerName() { - String serverName = ""; - try { - InetAddress myHost = InetAddress.getLocalHost(); - serverName = myHost.getHostName(); - } catch (UnknownHostException ex) { - ex.printStackTrace(); - } - return serverName; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TaskState.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TaskState.java deleted file mode 100644 index 1bc00f56405..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TaskState.java +++ /dev/null @@ -1,27 +0,0 @@ -package portal.guitest.common; - -public enum TaskState { - - OPEN, IN_PROGRESS, DONE, DESTROYED, DELAYED, ERROR; - - public static TaskState fromClass(String stateClass) { - switch (stateClass.trim()) { - case "in_progress-task-state": - return IN_PROGRESS; - - case "error-task-state": - return ERROR; - - case "done-task-state": - return DONE; - - case "destroyed-task-state": - return DESTROYED; - - case "delayed-task-state": - return DELAYED; - default: - return OPEN; - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestAccount.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestAccount.java deleted file mode 100644 index 72890ce574a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestAccount.java +++ /dev/null @@ -1,94 +0,0 @@ -package portal.guitest.common; - -import java.util.Optional; - -public enum TestAccount { - - GUEST_USER(nameOfGuestUser(), passwordOfGuestUser(), "Portal Guest User"), - - DEMO_USER(nameOfDemoUser(), passwordOfDemoUser(), "Portal Demo User"), - - ADMIN_USER(nameOfAdminUser(), passwordOfAdminUser(), "Portal Admin User"), - - HR_ROLE_USER(nameOfHrRoleUser(), passwordOfHrRoleUser(), "david"), - - TEST_CHANGE_PASSWORD_USER("test_change_password_user", "123", "Elton"), - - TEST_RELATED_TASKS_USER("test_related_tasks_user", "+d3m0++", "Related Tasks User"), - - CASE_OWNER_USER("caseOwnerUser", "caseOwnerUser", "caseOwnerUser"), - - TEST_FORGOT_PASSWORD_USER("test_forgot_password_user", "123", "Forgot Password User", "wawa@axongroupio.ch"); - - private String username; - private String password; - private String fullName; - private String email; - - private TestAccount(String username, String password, String fullName) { - this.username = username; - this.password = password; - this.fullName = fullName; - } - - private TestAccount(String username, String password, String fullName, String email) { - this(username, password, fullName); - this.email = email; - } - - private static String nameOfGuestUser() { - String userName = System.getProperty("guestUserName"); - return userName != null ? userName : "guest"; - } - - private static String passwordOfGuestUser() { - String password = System.getProperty("guestUserPassword"); - return password != null ? password : "guest"; - } - - private static String nameOfDemoUser() { - String userName = System.getProperty("demoUserName"); - return userName != null ? userName : "demo"; - } - - private static String passwordOfDemoUser() { - String password = System.getProperty("demoUserPassword"); - return password != null ? password : "demo"; - } - - private static String nameOfAdminUser() { - String userName = System.getProperty("adminUserName"); - return Optional.ofNullable(userName).orElse("admin"); - } - - private static String passwordOfAdminUser() { - String password = System.getProperty("adminUserPassword"); - return Optional.ofNullable(password).orElse("admin"); - } - - private static String nameOfHrRoleUser() { - String userName = System.getProperty("hrRoleUserName"); - return Optional.ofNullable(userName).orElse("david"); - } - - private static String passwordOfHrRoleUser() { - String password = System.getProperty("hrRoleUserPassword"); - return Optional.ofNullable(password).orElse("david"); - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } - - public String getFullName() { - return fullName; - } - - public String getEmail() { - return email; - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestRole.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestRole.java deleted file mode 100644 index 2c642367742..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/TestRole.java +++ /dev/null @@ -1,7 +0,0 @@ -package portal.guitest.common; - -public class TestRole { - public static final String EVERYBODY_ROLE = "Everybody"; - public static final String HR_ROLE = "Human resources department"; - public static final String TESTER_ROLE = "Tester"; -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/UrlHelpers.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/UrlHelpers.java deleted file mode 100644 index fd2cdfeeec4..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/UrlHelpers.java +++ /dev/null @@ -1,44 +0,0 @@ -package portal.guitest.common; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Optional; - -import org.apache.commons.lang.WordUtils; - -public class UrlHelpers { - - public static String generateAbsoluteProcessStartLink(String relativeProcessStartLink) { - //We renamed PortalExamples project to portal-developer-examples, so no need to capitalize first character of this project - //we combined PortalStyle, PortalKit and PortalTemplate to portal, so no need to capitalize first character of this project - if (!relativeProcessStartLink.contains("portal/") && !relativeProcessStartLink.contains("portal-developer-examples") - && !relativeProcessStartLink.contains("portal-user-examples") && !relativeProcessStartLink.contains("portal-components-examples") && !relativeProcessStartLink.contains("axonivy-express")) { - relativeProcessStartLink = WordUtils.capitalize(relativeProcessStartLink); - } - if (relativeProcessStartLink.endsWith(".icm")) { - return getEngineUrl() + getApplicationName() + "/casemap/" + relativeProcessStartLink; - } - return getEngineUrl() + getApplicationName() + "/pro/" + relativeProcessStartLink; - } - - private static String getApplicationName() { - String applicationName = System.getProperty("test.engine.app"); - return Optional.ofNullable(applicationName).orElse(PropertyLoader.getApplicationName()); - } - - private static String getEngineUrl() { - String vmArgUrl = System.getProperty("test.engine.url"); - if (vmArgUrl != null) { - try { - URL originalURL = new URL(vmArgUrl); - URL newURL = new URL(originalURL.getProtocol(), "localhost", originalURL.getPort(), originalURL.getFile()); - return newURL.toString(); - } catch (MalformedURLException e) { - throw new PortalGUITestException("Wrong Engine URL"); - } - - } else { - return "http://" + PropertyLoader.getServerAddress() + ":" + PropertyLoader.getIvyEnginePort() + "/"; - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Variable.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Variable.java deleted file mode 100644 index 6317b1ecbdc..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/Variable.java +++ /dev/null @@ -1,76 +0,0 @@ -package portal.guitest.common; - -public enum Variable { - - HIDE_LOGOUT_BUTTON("Portal.UserMenu.HideLogoutMenu"), - HIDE_CHANGE_PASSWORD_BUTTON("Portal.UserMenu.HideChangePasswordMenu"), - ENABLE_SCRIPT_CHECKING_FOR_UPLOADED_DOCUMENT("Portal.Document.EnableScriptChecking"), - ENABLE_VIRUS_SCANNER_FOR_UPLOADED_DOCUMENT("Portal.Document.EnableVirusScanner"), - UPLOAD_DOCUMENT_WHITELIST_EXTENSION("Portal.Document.WhitelistExtension"), - HIDE_TIME("Portal.DateTimeFormat.HideTime"), - HIDE_YEAR("Portal.DateTimeFormat.HideYear"), - HIDE_SYSTEM_TASKS_FROM_HISTORY("Portal.Histories.HideSystemTasks"), - HIDE_SYSTEM_TASKS_FROM_HISTORY_ADMINISTRATOR("Portal.Histories.HideSystemTasksForAdministrator"), - HIDE_SYSTEM_NOTES_FROM_HISTORY("Portal.Histories.HideSystemNotes"), - HIDE_SYSTEM_NOTES_FROM_HISTORY_ADMINISTRATOR("Portal.Histories.HideSystemNotesForAdministrator"), - HIDE_STATISTIC_WIDGET("Portal.Dashboard.HideStatisticWidget"), - ENABLE_GROUP_CHAT("Portal.Chat.EnableGroup"), - ENABLE_PRIVATE_CHAT("Portal.Chat.EnablePrivate"), - CHAT_RESPONSE_TIMEOUT("Portal.Chat.ResponseTimeout"), - CHAT_MAX_CONNECTION("Portal.Chat.MaxConnection"), - ENABLE_CASE_OWNER("Portal.Cases.EnableOwner"), - DISABLE_CASE_COUNT("Portal.Cases.DisableCount"), - DEFAULT_SORT_FIELD_OF_CASE_LIST("Portal.Cases.SortField"), - DEFAULT_SORT_DIRECTION_OF_CASE_LIST("Portal.Cases.SortDirection"), - REFRESH_TASK_LIST_INTERVAL("Portal.Tasks.RefreshInterval"), - DISABLE_TASK_COUNT("Portal.Tasks.DisableCount"), - DEFAULT_SORT_FIELD_OF_TASK_LIST("Portal.Tasks.SortField"), - DEFAULT_SORT_DIRECTION_OF_TASK_LIST("Portal.Tasks.SortDirection"), - SHOW_TASK_DURATION_TIME("Portal.TaskDetails.ShowDurationTime"), - HIDE_TASK_DOCUMENT("Portal.TaskDetails.HideDocument"), - HIDE_CASE_DOCUMENT("Portal.CaseDetails.HideDocument"), - SHOW_CASE_DURATION_TIME("Portal.CaseDetails.ShowDurationTime"), - HIDE_UPLOAD_DOCUMENT_FOR_DONE_CASE("Portal.CaseDetails.HideUploadDocumentForDoneCase"), - DEFAULT_PROCESS_MODE("Portal.Processes.Mode"), - DEFAULT_PROCESS_IMAGE("Portal.Processes.DefaultImage"), - DISPLAY_MESSAGE_AFTER_FINISH_TASK("Portal.DisplayMessageAfterFinishTask"), - EXPRESS_END_PAGE("Portal.ExpressEndPage"), - CLIENT_SIDE_TIMEOUT("Portal.ClientSideTimeout"), - EMBED_IN_FRAME("Portal.EmbedInFrame"), - LOGGED_IN_USER_FORMAT("Portal.LoggedInUserFormat"), - SHOW_GLOBAL_SEARCH("Portal.ShowGlobalSearch"), - SHOW_BUTTON_ICON("Portal.ShowButtonIcon"), - DEFAULT_NEWDASHBOARDPAGE("Portal.NewDashboardPage"), - DISPLAY_USERS_OF_TASK_ACTIVATOR("Portal.DisplayUsersOfRole"), - ANNOUNCEMENT("Portal.Announcement"), - TASK_ANALYSIS_FILTER("Portal.TaskAnalysisFilters"), - THIRD_PARTY_APP("Portal.ThirdPartyApplications"), - STATISTIC_CHART("Portal.StatisticCharts"), - EXTERNAL_LINK("Portal.Processes.ExternalLinks"), - EXPRESS_PROCESS("Portal.Processes.ExpressProcesses"), - TASK_COLUMN("Portal.Tasks.TaskColumn"), - TASK_FILTER("Portal.Tasks.TaskFilters"), - TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST("Portal.Tasks.BehaviourWhenClickingOnLineInTaskList"), - TASK_DETAIL("Portal.TaskDetails"), - CASE_COLUMN("Portal.Cases.CaseColumn"), - CASE_FILTER( "Portal.Cases.CaseFilters"), - CASE_DETAIL("Portal.CaseDetails"), - HIDE_RELATED_CASE_INFO_FROM_HISTORY("Portal.Histories.HideRelatedCaseInfo"), - USER_MENU("Portal.UserMenu"), - ENABLE_SWITCH_THEME_BUTTON("Portal.Theme.EnableSwitchThemeModeButton"), - DEFAULT_THEME_MODE("Portal.Theme.Mode"), - GLOBAL_FOOTER_INFO("Portal.GlobalFooterInfo"), - DEEPL_AUTH_KEY("Portal.DeepL.AuthKey"), ENABLE_DEEPL_TRANSLATION("Portal.DeepL.Enable"), - DASHBOARD("Portal.Dashboard"); - - private String key; - - private Variable(String key) { - this.key = key; - } - - public String getKey() { - return key; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/WaitHelper.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/WaitHelper.java deleted file mode 100644 index 6c87e855da7..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/common/WaitHelper.java +++ /dev/null @@ -1,122 +0,0 @@ -package portal.guitest.common; - -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.page.TemplatePage; -import vn.wawa.guitest.base.page.AbstractPage; - -public final class WaitHelper { - - /** - * Uses this method to wait then assertTrue. Instead of Assert#assertTrue(boolean), this method will wait until the - * condition is true or timeout - * - * @param supplier - * @param durationInSeconds - */ - public static void assertTrueWithWait(Supplier supplier, int durationInSeconds) { - Awaitility.await().atMost(new Duration(durationInSeconds, TimeUnit.SECONDS)).until(() -> { - try { - return supplier.get(); - } catch (Exception e) { - System.out.println("ERROR when assertTrueWithWait"); - } - return false; - }); - } - - /** - * Uses this method to wait then assertTrue. Instead of Assert#assertTrue(boolean), this method will wait 10 SECONDS - * until the condition is true or timeout - * - * @param supplier - */ - public static void assertTrueWithWait(Supplier supplier) { - assertTrueWithWait(supplier, 10); - } - - public static void assertTrueWithRefreshPage(TemplatePage page, Supplier supplier) { - Awaitility.await().atMost(new Duration(10, TimeUnit.SECONDS)).until(() -> { - try { - boolean result = supplier.get(); - if (!result) { - Sleeper.sleep(1000); // Wait for latest data - result = supplier.get(); - if (!result) { - System.out.println("Refresh page for latest data"); - waitForNavigation(page, () -> page.refresh()); - } - } - return supplier.get(); - } catch (Exception e) { - System.out.println("ERROR when assertTrueWithRefreshPage"); - Sleeper.sleep(1000); - try { - supplier.get(); - } catch (Exception e1) { - waitForNavigation(page, () -> page.refresh()); - } - } - return false; - }); - } - - public static void waitForNavigation(TemplatePage page, Runnable navigationAcion) { - String viewState = page.findElementByCssSelector("input[name='javax.faces.ViewState']").getAttribute("value"); - navigationAcion.run(); - page.waitForElementPresent(By.cssSelector("input[value='" + viewState + "']"), false); - page.waitForElementDisplayed("id('global-search-item')", true); - } - - public static void retryAction(Runnable action) { - int attempts = 0; - while (attempts < 10) { - try { - action.run(); - break; - } catch (Exception e) { - System.out.println("ERROR action"); - } - attempts++; - } - if (attempts == 10) { - action.run(); - } - } - - public static void typeWithRetry(AbstractPage page, String cssSelector, String value) { - WaitHelper.assertTrueWithWait(() -> { - WebElement input = page.findElementByCssSelector(cssSelector); - input.clear(); - input.click(); // To make Firefox more stable - input.sendKeys(value); - return input.getAttribute("value").equals(value); - }); - } - - public static void waitForIFrameAvailable(WebDriver driver, String frameId) { - wait(driver).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameId)); - } - - public static WebDriverWait wait(WebDriver driver) { - return new WebDriverWait(driver, 9L); - } - - public static void waitForPresenceOfElementLocatedInFrame(WebDriver driver, String cssSelector) { - wait(driver).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector))); - } - - public static void waitForVisibilityOfElementLocated(WebDriver driver, String cssSelector) { - wait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssSelector))); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AbsencePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AbsencePage.java deleted file mode 100644 index 451edc09de6..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AbsencePage.java +++ /dev/null @@ -1,191 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.apache.commons.collections4.CollectionUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import ch.ivy.addon.portalkit.enums.DeputyRoleType; - -public class AbsencePage extends TemplatePage { - - private static final String DELETE_ABSENCE__LINK_ID_PATTERN = "absences-management-form:absence-table:%d:delete-absence"; - private static final String EDIT_ABSENCE__LINK_ID_PATTERN = "absences-management-form:absence-table:%d:edit-absence"; - - @Override - protected String getLoadedLocator() { - return "id('absences-management-form')"; - } - - public NewAbsencePage openNewAbsenceDialog() { - String selector = "button[id*='add-absence']"; - waitForElementDisplayed(By.cssSelector(selector), true); - clickByCssSelector(selector); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "absence-form\\\\:absence-start-date_input", ID_PROPERTY); - return new NewAbsencePage(); - } - - public int countAbsences() { - waitForElementDisplayed(By.cssSelector("div[id*='absence-table']"), true); - return findListElementsByCssSelector("td.absence-period").size(); - } - - public void showAbsencesInThePast(boolean shown) { - WebElement checkBox = findElementByCssSelector("input[id*='show-absence-in-the-past']"); - boolean checkBoxSelected = checkBox.isSelected(); - if (checkBoxSelected != shown) { - clickByCssSelector("div[id*='show-absence-in-the-past'] div.ui-chkbox-box"); - waitUntilAnimationFinished(DEFAULT_TIMEOUT,"ajax-indicator:ajax-indicator-ajax-indicator_start" , "id"); - } - } - - public String getMyDeputy(int deputyRoleIndex) { - String deputiesSelector = String.format("a[id$='absences-management-form:substitute-table:%d:selected-deputies-link']", deputyRoleIndex); - waitForElementDisplayed(By.cssSelector(deputiesSelector), true); - return findElementByCssSelector(deputiesSelector).getText(); - } - - public String getMyDisabledDeputy(int deputyRoleIndex) { - String deputiesSelector = String.format("span[id$='absences-management-form:substitute-table:%d:selected-deputies-link']", deputyRoleIndex); - waitForElementDisplayed(By.cssSelector(deputiesSelector), true); - return findElementByCssSelector(deputiesSelector).getText(); - } - - public String getIAMDeputyFor() { - List noteAuthorElements = findListElementsByCssSelector("tbody[id*='substitution-table_data'] > tr > td"); - return noteAuthorElements.stream().map(w -> w.getText()).collect(Collectors.joining()); - } - - public int indexOfDeputyRole(DeputyRoleType deputyRoleType) { - String deputyRoleTypeSelector = ".substitute-table .substition-role-type"; - List elements = findListElementsByCssSelector(deputyRoleTypeSelector); - if (CollectionUtils.isNotEmpty(elements)) { - for (int index = 0; index < elements.size(); index++) { - WebElement element = elements.get(index); - String deputyRoleTypeValue = element.getAttribute("deputy-role-type"); - if (deputyRoleTypeValue != null && deputyRoleTypeValue.equals(String.valueOf(deputyRoleType))) { - return index; - } - } - } - return -1; - } - - public void setDeputy(List fullNames, DeputyRoleType deputyRoleType) { - setDeputy(fullNames, indexOfDeputyRole(deputyRoleType), true); - } - - public void setDeputy(List fullNames, DeputyRoleType deputyRoleType, boolean saveSelectedDeputies) { - setDeputy(fullNames, indexOfDeputyRole(deputyRoleType), saveSelectedDeputies); - } - - public void setDeputy(List fullNames, int deputyRoleIndex) { - setDeputy(fullNames, deputyRoleIndex, true); - } - - public void setDeputy(List fullNames, int deputyRoleIndex, boolean saveSelectedDeputies) { - try { - clickSelectedDeputiesLink(deputyRoleIndex); - } catch (Exception e) { - clickSelectedDeputiesLink(deputyRoleIndex); - } - for (String fullName : fullNames) { - selectDeputy(fullName); - } - if (saveSelectedDeputies) { - click(By.id("deputy-selection-form:save-deputy-button")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - } - - private void clickSelectedDeputiesLink(int deputyRoleIndex) { - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - String deputiesSelector = String.format("a[id$='absences-management-form:substitute-table:%d:selected-deputies-link']", deputyRoleIndex); - waitForElementReallyDisplayed(By.cssSelector(deputiesSelector), true); - Awaitility.await().atMost(new Duration(10, TimeUnit.SECONDS)).until(() -> { - try { - WebElement deputiesLink = findElementByCssSelector(deputiesSelector); - deputiesLink.click(); - } catch (Exception e) { - // to avoid choose-deputy-dialog displays before deputiesLink is clicked - } - try { - return findElementById("choose-deputy-dialog").isDisplayed(); - } catch (Exception e) { - return false; - } - }); - } - - private void selectDeputy(String responsible) { - type(By.id("deputy-selection-form:user-selection-component:user-selection_input"), responsible); - waitForElementDisplayed(By.id("deputy-selection-form:user-selection-component:user-selection_panel"), true); - click(By.xpath("//*[@id='deputy-selection-form:user-selection-component:user-selection_panel']/table/tbody/tr")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - click(By.id("deputy-selection-form:add-deputy-button")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public String getChooseDeputyDialogError() { - String errorMessageDiv = "div[id$='deputy-selection-form:error-message']"; - waitForElementDisplayed(By.cssSelector(errorMessageDiv), true); - return findChildElementByCssSelector(findElementByCssSelector(errorMessageDiv), ".ui-messages-error-detail").getText(); - } - - public void setSubstitutedByAdmin(String substitutedUser) { - String selectedUserInput = "input[id$=':user-absence-selection-component:user-absence_input']"; - waitForElementDisplayed(By.cssSelector(selectedUserInput), true); - WebElement substituted = findElementByCssSelector(selectedUserInput); - substituted.clear(); - substituted.sendKeys(substitutedUser); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - String itemSelector = "tr[data-item-label*='" + substitutedUser + "']"; - waitForElementDisplayed(By.cssSelector(itemSelector), true); - clickByCssSelector(itemSelector); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public String getSubstitutedByAdmin(int rowIndex) { - WebElement deputyForTable = findElementByCssSelector("[id$=':substitution-table']"); - WebElement deputyFor = deputyForTable.findElements(By.cssSelector(".name-after-avatar")).get(rowIndex); - return deputyFor.getText(); - } - - @SuppressWarnings("deprecation") - public void saveSubstitute() { - clickByCssSelector("button[id$='absences-management-form:save-substitute']"); - waitAjaxIndicatorDisappear(); - } - - public WebElement getAbsenceForm() { - return findElementById("absences-management-form"); - } - - public WebElement getAddAbsenceDialog() { - return findElementById("absence-dialog"); - } - - public void waitForAbsencesGrowlMessageDisplay() { - WebElement growlMessage = findElementByCssSelector("div[id$='absences-management-form:absences-management-info_container']"); - waitForElementDisplayed(growlMessage.findElement(By.className("ui-growl-item-container")), true, 5); - } - - public boolean canDeleteAbsence(int index) { - return findElementById(String.format(DELETE_ABSENCE__LINK_ID_PATTERN, index)).isDisplayed(); - } - - public boolean canEditAbsence(int index) { - return findElementById(String.format(EDIT_ABSENCE__LINK_ID_PATTERN, index)).isDisplayed(); - } - - public boolean isDeputySettingSectionDisplayed() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT,"ajax-indicator:ajax-indicator-ajax-indicator_start" , "id"); - return isElementPresent(By.id("deputy-setting")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdditionalCaseDetailsPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdditionalCaseDetailsPage.java deleted file mode 100644 index aa246022787..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdditionalCaseDetailsPage.java +++ /dev/null @@ -1,18 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class AdditionalCaseDetailsPage extends TemplatePage { - - private static final String TABLE_ROWS_PATH = "div[id$='additional-case-detail-table'] tbody>tr"; - - public int countFields() { - switchToIFrameOfTask(); - waitForElementDisplayed(By.cssSelector("div[id$='additional-case-detail-table']"), true); - return driver.findElements(By.cssSelector(TABLE_ROWS_PATH)).size(); - } - - public String getAdditionalFieldContentOfFirstRow() { - return findElementByCssSelector("#additional-case-detail-table\\:0\\:value").getText(); - } -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdhocPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdhocPage.java deleted file mode 100644 index 115b4a943fb..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdhocPage.java +++ /dev/null @@ -1,38 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.WebElement; - - -public class AdhocPage extends TaskTemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('request-tab')"; - } - - public void enterSubject(String subject) { - WebElement subjectInput = findElementByCssSelector("*[id$='" + ":dataCaseInfoSubject']"); - type(subjectInput, subject); - } - - public void addTask() { - clickByCssSelector("*[id$='" + ":add-task']"); - } - - public void addComment(String comment) { - WebElement commentInput = findElementByCssSelector("*[id$='" + ":comments']"); - type(commentInput, comment); - } - - public TaskWidgetPage startWorkflow() { - clickByCssSelector("*[id$='" + ":start-workflow']"); - return new TaskWidgetPage(); - } - - public TaskWidgetPage send() { - clickByCssSelector("*[id$='" + ":send']"); - return new TaskWidgetPage(); - } - - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdminSettingsPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdminSettingsPage.java deleted file mode 100644 index 91834abc914..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AdminSettingsPage.java +++ /dev/null @@ -1,176 +0,0 @@ -package portal.guitest.page; - -import static portal.guitest.common.Variable.CLIENT_SIDE_TIMEOUT; -import static portal.guitest.common.Variable.GLOBAL_FOOTER_INFO; - -import java.util.List; - -import org.apache.commons.collections.CollectionUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class AdminSettingsPage extends TemplatePage { - - private static final String PORTAL_MANAGEMENT_PAGE_ID = "portal-management-container"; - - public AdminSettingsPage() { - waitForElementDisplayed(By.id(PORTAL_MANAGEMENT_PAGE_ID), true); - } - - @Override - protected String getLoadedLocator() { - return "id('" + PORTAL_MANAGEMENT_PAGE_ID + "')"; - } - - @Override - public boolean isDisplayed() { - return findElementById(PORTAL_MANAGEMENT_PAGE_ID).isDisplayed(); - } - - @SuppressWarnings("deprecation") - public void openSettingTab() { - WebElement settingTabLink = findElementByCssSelector("a[href$='#admin-setting-component:adminTabView:setting-tab']"); - click(settingTabLink); - waitForElementPresent(By.cssSelector("[id$=':adminTabView:settingForm']"), true); - waitAjaxIndicatorDisappear(); - } - - private void editGlobalVariable(String variableName, String variableValue, boolean isBooleanType) { - List tableRows = getAdminTable().findElements(By.tagName("tr")); - for (WebElement row : tableRows) { - List columns = row.findElements(By.tagName("td")); - if (!CollectionUtils.isEmpty(columns)) { - WebElement keyColumn = columns.get(0); - if (keyColumn.getText().equals(variableName)) { - WebElement editButton = row.findElement(By.cssSelector("a[id$=edit]")); - click(editButton); - waitForElementPresent(By.cssSelector("[id$=':settingDialogForm']"), true); - saveGlobalVariable(variableValue, isBooleanType); - return; - } - } - } - } - - private WebElement getAdminTable() { - return findElementByCssSelector("[id$=':adminTabView:settingTable']"); - } - - public void resetAllSettings() { - openSettingTab(); - WebElement restoreAllToDefaultButton = findElementById("admin-setting-component:adminTabView:restore-all-to-default-button"); - click(restoreAllToDefaultButton); - waitForElementPresent(By.id("admin-setting-component:reset-settings"), true); - WebElement restoreButton = findElementById("admin-setting-component:reset-settings"); - click(restoreButton); - closeConfirmationDialog(); - } - - private void saveGlobalVariable(String value, boolean isBooleanType) { - if (!isBooleanType) { - WebElement valueInput = findElementById("admin-setting-component:valueSetting"); - valueInput.clear(); - valueInput.sendKeys(value); - } else { - click(By.id("admin-setting-component:valueSetting_label")); - waitForElementDisplayed(By.id("admin-setting-component:valueSetting_panel"), true); - boolean boolValue = Boolean.parseBoolean(value); - int index = boolValue ? 1 : 0; - click(By.id(String.format("admin-setting-component:valueSetting_%d", index))); - } - WebElement saveButton = findElementById("admin-setting-component:save-setting"); - click(saveButton); - } - - public void clickOnbackToNewDashboardPageOnAdminSetting() { - WebElement closeButton = findElementById("back-to-home-button"); - WaitHelper.waitForNavigation(this, () -> click(closeButton)); - } - - public void setClientSideTimeout(String timeout) { - openSettingTab(); - editGlobalVariable(CLIENT_SIDE_TIMEOUT.getKey(), timeout, false); - closeConfirmationDialog(); - } - - public void closeConfirmationDialog() { - clickOnbackToNewDashboardPageOnAdminSetting(); - } - - public void setGlobalFooterInfo() { - openSettingTab(); - editGlobalVariable(GLOBAL_FOOTER_INFO.getKey(), "Dev Team: Wawa, Env: Dev", false); - closeConfirmationDialog(); - } - - public boolean isWarningDialogShowWhenTimeoutIsLosing() { - waitForElementDisplayed(By.cssSelector("div[id$=':timeout-warning-dialog']"), true, 121); - return isElementDisplayed(By.cssSelector("div[id$=':timeout-warning-dialog']")); - } - - public boolean isInformDialogShowAfterTimeout() { - waitForElementDisplayed(By.id("warning-before-lost-session:timeout-dialog"), true, 181); - return isElementDisplayed(By.id("warning-before-lost-session:timeout-dialog")); - } - - @SuppressWarnings("deprecation") - public AnnouncementPage openAnnouncementTab() { - WebElement settingTabLink = findElementByXpath("//a[@href='#admin-setting-component:adminTabView:announcement-tab']"); - click(settingTabLink); - waitForElementPresent(By.id("admin-setting-component:adminTabView:announcement-tab"), true); - waitAjaxIndicatorDisappear(); - return new AnnouncementPage(); - } - - @SuppressWarnings("deprecation") - public ExpressManagementPage openExpressManagementTab() { - WebElement settingTabLink = findElementByXpath("//a[@href='#admin-setting-component:adminTabView:express-management-tab']"); - click(settingTabLink); - waitForElementPresent(By.id("admin-setting-component:adminTabView:express-management-tab"), true); - waitAjaxIndicatorDisappear(); - return new ExpressManagementPage(); - } - - public RoleManagementPage openRoleManagementTab() { - waitForElementDisplayed(By.cssSelector("[id$='admin-setting-component:adminTabView']"), true); - clickByCssSelector("a[href='#admin-setting-component:adminTabView:role-management-tab']"); - waitForElementPresent(By.cssSelector("[id$=':role-management-component:role-management-form:role-tree-table']"), true); - return new RoleManagementPage(); - } - - public boolean isRoleAssingmentTabViewPresent() { - return isElementPresent(By.cssSelector("a[href='#admin-setting-component:adminTabView:role-management-tab']")); - } - - public boolean isPasswordValidationTabViewPresent() { - return isElementPresent(By.cssSelector("a[href='#admin-setting-component:adminTabView:password-validation-tab']")); - } - - public PasswordValidationPage openPasswordValidationTab() { - waitForElementDisplayed(By.cssSelector("[id$='admin-setting-component:adminTabView']"), true); - clickByCssSelector("a[href='#admin-setting-component:adminTabView:password-validation-tab']"); - waitForElementPresent(By.cssSelector("[id$=':password-validation-component:password-validation-form:password-policy-setting']"), true); - return new PasswordValidationPage(); - } - - public WebElement getAdminSettingContainer() { - return findElementById("admin-settings-container"); - } - - public WebElement getAddApplicationDialog( ) { - click(By.id("admin-setting-component:adminTabView:add-application-btn")); - waitForElementDisplayed(By.id("admin-setting-component:appDialog"), true); - Sleeper.sleep(300);//Wait a bit focus effects, just only use this for capture screenshot - return findElementById("admin-setting-component:appDialog"); - } - - public WebElement getEditSettingDialogOfFirstRow() { - click(By.id("admin-setting-component:adminTabView:settingTable:0:edit")); - waitForElementDisplayed(By.id("admin-setting-component:settingDialog"), true); - Sleeper.sleep(300);//Wait a bit focus effects, just only use this for capture screenshot - return findElementById("admin-setting-component:settingDialog"); - } -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AnnouncementPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AnnouncementPage.java deleted file mode 100644 index b672b7a0093..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/AnnouncementPage.java +++ /dev/null @@ -1,33 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class AnnouncementPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('admin-setting-component:adminTabView:announcement-tab')"; - } - - public String getInfoSummary() { - return driver.findElement(By.cssSelector("div[id$='messages'] span[class$='summary']")).getText(); - } - - @SuppressWarnings("deprecation") - public void publish() { - clickByCssSelector("button[id$='publish-announcement']"); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void dePublish() { - clickByCssSelector("button[id$='delete-announcement']"); - waitAjaxIndicatorDisappear(); - } - - public void setAnnoucement(int Language, String content) { - findElementByCssSelector("input[id$='" + Language + ":announcement-input']").sendKeys(content); - } - - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseDetailsPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseDetailsPage.java deleted file mode 100644 index 53369bfca07..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseDetailsPage.java +++ /dev/null @@ -1,915 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.Action; -import org.openqa.selenium.interactions.Actions; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import ch.ivyteam.ivy.workflow.task.TaskBusinessState; -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class CaseDetailsPage extends TemplatePage { - private static final String CLASS = "class"; - private static final String DONE_TASKS_SELECTOR = "td.related-task-state-column .task-state.done-task-state"; - private static final String DOCUMENT_COMPONENT_ID = "div[id='case-details-document-panel']"; - private static final String HISTORY_COMPONENT_ID = "div[id='case-details-history-panel']"; - private static final String RELATED_TASKS_COMPONENT_ID = "div[id='case-details-relatedTask-panel']"; - private static final String RELATED_CASES_COMPONENT_ID = "div[id='case-details-technicalCase-panel']"; - private static final String HISTORY_LIST_CSS_SELECTOR = "td.history-note a[id*=':case-histories:case-histories:']"; - private static final String LATEST_HISTORY_LIST_CSS_SELECTOR = "a[id*=':case-histories:case-histories:0:note-link']"; - private static final String GENERAL_INFORMATION_COMPONENT_ID = "div[id='case-details-information-panel']"; - private static final String ADDITIONAL_CASE_DETAILS_URL_CSS_SELECTOR = "a[id$=':show-additional-case-details-link']"; - private static final String PROCESS_OVERVIEW_URL_CSS_SELECTOR = "a[id$=':show-process-overview-link']"; - private static final String VIEW_NOTE_DIALOG_SELECTOR = "[id$=':case-histories:view-note-dialog']"; - private WebElement caseItem; - - @Override - protected String getLoadedLocator() { - return "id('case-item-details:case-details-container:case-detail-body')"; - } - - public CaseDetailsPage() { - this.caseItem = findElementByCssSelector("#main-area-panel"); - } - - public String getCaseDuration() { - return caseItem.findElement(By.cssSelector("span[id$='case-duration-time']")).getText(); - } - - public String getCaseCategory() { - return caseItem.findElement(By.cssSelector("span[id$='case-category']")).getText(); - } - - public String getCaseState() { - return caseItem.findElement(By.cssSelector("span.state-with-indicator > span")).getText(); - } - - public boolean isBusinessCaseInformationSectionDisplayed() { - return isElementDisplayed(By.cssSelector("div[id$='business-case-information']")); - } - - public CaseDetailsPage openBusinessCaseFromTechnicalCase() { - caseItem.findElement(By.cssSelector("a[id$='related-business-case']")).click(); - waitForElementPresent(By.cssSelector("div[id$='business-case-information']"), false); - return new CaseDetailsPage(); - } - - public int getNumberOfHistory() { - return caseItem.findElements(By.cssSelector(HISTORY_LIST_CSS_SELECTOR)).size(); - } - - public int countRelatedTasks() { - return caseItem.findElement(By.cssSelector("div[id$='related-tasks']")) - .findElements(By.cssSelector("td.related-task-name-column")).size(); - } - - public int countRelatedDoneTasks() { - return caseItem.findElement(By.cssSelector("div[id$='related-tasks']")) - .findElements(By.cssSelector(".task-state.done-task-state")).size(); - } - - public boolean checkDoneTasksOfHistory() { - List taskNames = caseItem.findElement(By.cssSelector("div[id$='related-tasks']")) - .findElements(By.cssSelector("span.task-name-value")); - List taskStates = caseItem.findElement(By.cssSelector("div[id$='related-tasks']")) - .findElements(By.cssSelector("span.task-state")); - List histories = caseItem.findElement(By.cssSelector("div[id$='case-histories']")) - .findElements(By.cssSelector("a.task-note-link")); - if (CollectionUtils.isNotEmpty(taskStates)) { - String DONE = "Done"; - for (int i = 0; i < taskStates.size(); i++) { - if (DONE.equals(taskStates.get(i).getText()) && !isHistoryExistent(histories, taskNames.get(i).getText())) { - return false; - } - } - } - return true; - } - - private boolean isHistoryExistent(List histories, String historyContent) { - for (WebElement history : histories) { - if (history.getText().equals(historyContent)) { - return true; - } - } - return false; - } - - public int countRelatedCases() { - return caseItem.findElement(By.cssSelector("div[id$='related-cases']")) - .findElements(By.cssSelector("td.name-column")).size(); - } - - public void addNote(String content) { - onClickHistoryIcon(); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div.ui-dialog[aria-hidden='false']"), true); - WebElement addNoteDialog = findElementByCssSelector("div.ui-dialog[aria-hidden='false']"); - waitForElementDisplayed(addNoteDialog, true); - addNoteDialog.findElement(By.cssSelector("textarea[id$='note-content']")).sendKeys(content); - click(addNoteDialog.findElement(By.cssSelector("button[id$='save-add-note-command']"))); - waitAjaxIndicatorDisappear(); - } - - public void showNoteHistory() { - click(findElementByCssSelector("a[id$='show-more-note-link']")); - } - - public String getLatestHistoryContent() { - return caseItem.findElement(By.cssSelector(LATEST_HISTORY_LIST_CSS_SELECTOR)).getText(); - } - - public void openAdditionalCaseDetailsPage() { - clickByCssSelector(ADDITIONAL_CASE_DETAILS_URL_CSS_SELECTOR); - } - - public void openProcessOverviewPage() { - clickByCssSelector(PROCESS_OVERVIEW_URL_CSS_SELECTOR); - } - - private WebElement getGeneralInformationComponent() { - return findElementByCssSelector(GENERAL_INFORMATION_COMPONENT_ID); - } - - public boolean isGeneralInformationComponentPresented() { - return getGeneralInformationComponent().isDisplayed(); - } - - private WebElement getRelatedTasksComponent() { - return findElementByCssSelector(RELATED_TASKS_COMPONENT_ID); - } - - public boolean isRelatedTasksComponentPresented() { - return getRelatedTasksComponent().isDisplayed(); - } - - public boolean isRelatedCasesComponentPresented() { - return getRelatedCasesComponent().isDisplayed(); - } - - private WebElement getRelatedCasesComponent() { - return findElementByCssSelector(RELATED_CASES_COMPONENT_ID); - } - - public boolean isHistoryComponentPresented() { - WebElement historyComponent = getHistoryComponent(); - return historyComponent.isDisplayed(); - } - - private WebElement getHistoryComponent() { - WebElement historyComponent = findElementByCssSelector(HISTORY_COMPONENT_ID); - return historyComponent; - } - - public boolean isDocumentComponentPresented() { - WebElement documentComponent = getDocumentComponent(); - return documentComponent.isDisplayed(); - } - - private WebElement getDocumentComponent() { - WebElement documentComponent = findElementByCssSelector(DOCUMENT_COMPONENT_ID); - return documentComponent; - } - - public TaskDetailsPage openTasksOfCasePage(int index) { - caseItem.findElement(By.cssSelector("div[id$='related-tasks']")) - .findElements(By.cssSelector("td.related-task-id-column")).get(index).click(); - return new TaskDetailsPage(); - } - - public TaskDetailsPage openTasksOfCasePage(String taskName) { - caseItem.findElement(By.cssSelector("div[id$='related-tasks']")) - .findElements(By.cssSelector("td.related-task-name-column")).stream() - .filter(element -> element.getText().equals(taskName)).findFirst().get().click(); - return new TaskDetailsPage(); - } - - public TaskDetailsPage openTasksOfCasePageViaDetailsAction(int index) { - String openDetailsCommandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-open-detail-command']", index); - waitForElementDisplayed(By.cssSelector(openDetailsCommandButton), true); - findElementByCssSelector(openDetailsCommandButton).click(); - return new TaskDetailsPage(); - } - - public CaseDetailsPage openCasesOfCasePageViaDetailsAction(int index) { - String openDetailsCommandButton = String.format("[id$='related-cases-widget:related-cases:%d:action-step-component:case-item-open-detail-link']", index); - waitForElementDisplayed(By.cssSelector(openDetailsCommandButton), true); - findElementByCssSelector(openDetailsCommandButton).click(); - waitForElementPresent(By.cssSelector(openDetailsCommandButton), false); - return new CaseDetailsPage(); - } - - public AdditionalCaseDetailsPage openRelatedCaseBusinessDetail(int index) { - String openDetailsCommandButton = String.format("[id$='related-cases-widget:related-cases:%d:action-step-component:show-additional-case-details-link']", index); - waitForElementDisplayed(By.cssSelector(openDetailsCommandButton), true); - findElementByCssSelector(openDetailsCommandButton).click(); - return new AdditionalCaseDetailsPage(); - } - - public NewDashboardPage clickRelatedCaseSubmitLeaveReason(int index) { - WebElement sideSteps = findElementByCssSelector(String.format("[id$='related-cases-widget:related-cases:%d:action-step-component:side-steps']", index)); - findChildElementByLinkText(sideSteps, "Submit leave reason").click(); - return new NewDashboardPage(); - } - - public NewDashboardPage clickRelatedCaseUploadAdditionalDocument(int index) { - WebElement sideSteps = findElementByCssSelector(String.format("[id$='related-cases-widget:related-cases:%d:action-step-component:side-steps']", index)); - findChildElementByLinkText(sideSteps, "Upload additional data").click(); - return new NewDashboardPage(); - } - - public String openDoneTask(int index) { - WebElement showTaskNoteLink = caseItem.findElements(By.cssSelector("a[id$='show-task-note-link']")).get(index); - String taskName = showTaskNoteLink.getText(); - click(showTaskNoteLink); - return taskName; - } - - public String getHistoryAuthor() { - return findElementByCssSelector(".history-fullname").getText(); - } - - public void clickViewNote() { - clickByCssSelector(LATEST_HISTORY_LIST_CSS_SELECTOR); - waitAjaxIndicatorDisappear(); - WebElement noteDialog = getViewNoteDialog(); - waitForElementDisplayed(noteDialog, true); - } - - public boolean isViewNoteDialogPresented() { - return getViewNoteDialog().isDisplayed(); - } - - public List getCaseNoteAuthors() { - List noteAuthorElements = - findListElementsByCssSelector("span.history-fullname"); - return noteAuthorElements.stream().map(w -> w.getText()).collect(Collectors.toList()); - } - - private WebElement getViewNoteDialog() { - return findElementByCssSelector(VIEW_NOTE_DIALOG_SELECTOR); - } - - public void changeCaseDescription(String newDescription) { - onClickDescriptionEditIcon(); - onChangeDescriptionInput(newDescription); - onSubmitDescriptionInplaceEditor(); - waitForPageLoaded(); - } - - private void onClickDescriptionEditIcon() { - waitForElementDisplayed(By.cssSelector("a[id$='general-information:description:edit-description-link']"), true); - click(By.cssSelector("a[id$='general-information:description:edit-description-link']")); - } - - private void onChangeDescriptionInput(String newDescription) { - WebElement caseDescriptionInput = findElementByCssSelector("textarea[id$='general-information:description:case-description-form:case-description-input']"); - waitForElementDisplayed(caseDescriptionInput, true); - caseDescriptionInput.clear(); - caseDescriptionInput.sendKeys(newDescription); - } - - private void onSubmitDescriptionInplaceEditor() { - WebElement editor = findElementByCssSelector("span[id$='general-information:description:case-description-form:case-description-inplace_editor']"); - WebElement saveButton = findChildElementByClassName(editor, "ui-inplace-save"); - clickByJavaScript(saveButton); - waitAjaxIndicatorDisappear(); - } - - public String getDescription() { - WebElement caseDescription = findElementByCssSelector("[id$='case-description-output']"); - waitForElementDisplayed(caseDescription, true); - return caseDescription.getText(); - } - - public boolean isCaseDescriptionChangeComponentPresented(int caseIndex) { - return isElementPresent(By - .id(String.format("case-widget:case-list-scroller:%d:case-item:case-body:case-description-input", caseIndex))); - } - - public CaseWidgetPage goBackToCaseListFromCaseDetails() { - clickBackButton(); - return new CaseWidgetPage(); - } - - public void onClickHistoryIcon() { - click(findElementByCssSelector("a[id$=':case-histories:add-note-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void onClickDestroyCase() { - click(findElementByCssSelector("a[id$=':action-group:destroy-case']")); - } - - public void confimDestruction() { - String destroyCaseDialogSelector = "[id$=':destroy-case-confirmation-dialog']"; - waitForElementDisplayed(By.cssSelector(destroyCaseDialogSelector), true); - WebElement destroyConfirmationDialog = findElementByCssSelector(destroyCaseDialogSelector); - WebElement confirmButton = findChildElementByCssSelector(destroyConfirmationDialog, "[id$=':confirm-destruction']"); - click(confirmButton); - } - - @Override - public void waitAjaxIndicatorDisappear() { - WebElement ajaxIndicatorStartState = findElementById("ajax-indicator:ajax-indicator-ajax-indicator_start"); - boolean displayed = false; - try { - displayed = ajaxIndicatorStartState.isDisplayed(); - } catch (Exception e) { - try { - displayed = ajaxIndicatorStartState.isDisplayed(); - } catch (Exception e1) { - System.out.println("Cannot check if ajax indicator is displayed"); - } - } - if (displayed) { - waitForElementDisplayed(ajaxIndicatorStartState, false); - } - } - - public TaskWidgetPage clickShowAllTasks() { - click(caseItem.findElement(By.cssSelector("a[id$='show-more-related-tasks']"))); - return new TaskWidgetPage(); - } - - public void uploadDocumentWithoutError(String pathToFile) { - Sleeper.sleep(2000);//slow down a bit for FF - openAddDocumentDialogAndUploadDocument(pathToFile); - waitForElementDisplayed(By.cssSelector("span[class$='ui-messages-info-summary']"), true); - click(By.cssSelector("button[id$='document:document-upload-close-command']")); - } - - public String uploadDocumentWithError(String pathToFile) { - openAddDocumentDialogAndUploadDocument(pathToFile); - WebElement errorMsg = findElementByCssSelector("div[id$='upload-messages']"); - String returnMsg = StringUtils.EMPTY; - if (errorMsg.isDisplayed()) { - returnMsg = errorMsg.getText(); - } - click(By.cssSelector("button[id$='document-upload-close-command']")); - return returnMsg; - } - - private void openAddDocumentDialogAndUploadDocument(String pathToFile) { - getAddAttachmentDialog(); - findElementByCssSelector("input[id$='document-upload-panel_input']").sendKeys(pathToFile); - // currently haven't found solution to check when the file upload finish, we have to wait - Sleeper.sleep(2000); - } - - public boolean isDeleteDocumentButtonPresented() { - return isElementDisplayed(By.cssSelector("a[id$='delete-file']")); - } - - public void removeAttachmentInCaseDocument(String filename) { - WebElement documentName = findElementByCssSelector("span[class$='js-document-name']"); - if (documentName.getText().equalsIgnoreCase(filename)) { - getDeleteDocumentConfirmDialog(); - findElementByCssSelector("button[id$='document-deletion-command']").click(); - } - } - - public WebElement getDeleteDocumentConfirmDialog() { - click(findElementByCssSelector("a[id$='delete-file']")); - waitForElementDisplayed(By.cssSelector("div[id$='document-deletion-dialog']"), true); - return findElementByCssSelector("div[id$='document-deletion-dialog']"); - } - - public WebElement findDeleteDocumentIcon() { - return findElementByCssSelector("a[id$='delete-file']"); - } - - public String getCaseName() { - return getTextOfCurrentBreadcrumb().replace("Case: ", ""); - } - - public String getCaseId() { - return findElementByCssSelector("span[id$='general-information:case-id']").getText(); - } - - public boolean isAddNoteButtonDisplayed() { - return isElementDisplayed(By.cssSelector("a[id$='case-histories:add-note-command']")); - } - - public boolean isShowMoreNoteButtonDisplayed() { - return isElementDisplayed(By.cssSelector("a[id$='case-histories:show-more-note-link']")); - } - - public boolean isShowDetailsDisplayed() { - return isElementDisplayed(By.cssSelector("a[id$='show-additional-case-details-link']")); - } - - public boolean isAddDocumentLinkDisplayed() { - return isElementDisplayed(By.cssSelector("a[id$='document:add-document-command']")); - } - - public int countNumberOfDocument() { - return findListElementsByCssSelector("a[id$='download']").size(); - } - - public List findDocumentItemInCaseDetailsDocumentTable() { - return findListElementsByCssSelector("a[id$='download']"); - } - - public void clickCaseListBreadCrumb() { - click(By.cssSelector(".portal-breadcrumb ol li:nth-of-type(2) .ui-menuitem-link")); - } - - public void clickBackButton() { - click(findElementById("case-item-details:case-details-container:back-to-cases")); - } - - public void openRelatedCaseOfBusinessCase(int index) { - WebElement findElement = caseItem.findElement(By.cssSelector("div[id$='related-cases']")); - if (findElement != null) { - findElement - .findElements(By.cssSelector("td.name-column")).get(index).click(); - } - waitForPageLoaded(); - } - - public void waitForCaseDetailsReload() { - waitForPageLoaded(); - Sleeper.sleep(3000); // currently, cannot find how to navigate to same page - waitForElementDisplayed(By.className("case-detail-body"), true); - } - - public void waitForCaseNameChanged(String caseName) { - waitForElementDisplayed(findElementByCssSelector(CURRENT_BREADCRUMB_SELECTOR), true); - Awaitility.waitAtMost(new Duration(60, TimeUnit.SECONDS)).until(() -> getTextOfCurrentBreadcrumb().contains(caseName)); - } - - public WebElement getGeneralInforBox() { - return findElementByCssSelector("[id$='case-detail-general-container']"); - } - - public WebElement getRelatedRunningTaskBox() { - return findElementByCssSelector("[id$='case-details-related-running-tasks-card']"); - } - - public WebElement getHistoriesBox() { - return findElementByCssSelector("[id$='history-container']"); - } - - public WebElement getDocumentBox() { - return findElementByCssSelector("[id$='case-details-document-card']"); - } - - public WebElement getAddNoteDialog() { - onClickHistoryIcon(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-inputtextarea.note-content-textarea", CLASS_PROPERTY); - return findElementByCssSelector("[id$='case-histories:add-note-dialog']"); - } - - public WebElement getAddAttachmentDialog() { - clickByCssSelector("a[id$='add-document-command']"); - waitForElementDisplayed(By.cssSelector("span[id$='document-upload-dialog_title']"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-dialog.case-upload-dialog", CLASS_PROPERTY); - return findElementByCssSelector("[id$='document:document-upload-dialog']"); - } - - public void waitForCaseDetailsDisplay() { - waitForElementDisplayed(By.id("case-item-details:case-details-container:case-detail-body"), true); - } - - public WebElement getSwitchToEditModeButton() { - return findElementByCssSelector("[id$=':switch-to-edit-mode-button']"); - } - - public WebElement getSwitchToViewModeButton() { - return findElementByCssSelector("[id$=':switch-to-view-mode-button']"); - } - - public WebElement getResetButton() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-details-settings-button']"), true); - return findElementByCssSelector("[id$=':reset-details-settings-button']"); - } - - public void resetToDefault() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-details-settings-button']"), true); - click(By.cssSelector("[id$=':reset-details-settings-button']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void confirmResetToDefault() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-to-default-case-form:confirm-destruction']"), true); - click(By.cssSelector("[id$=':reset-to-default-case-form:confirm-destruction']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void switchToEditMode() { - waitForElementDisplayed(By.cssSelector("[id$=':switch-to-edit-mode-button']"), true); - click(By.cssSelector("[id$=':switch-to-edit-mode-button']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - WaitHelper.assertTrueWithWait(() -> { - var infoWidget = findElementByCssSelector("[id$='case-details-information-panel']"); - return infoWidget.getAttribute(CLASS_PROPERTY).contains("ui-resizable ui-resizable-autohide"); - }); - } - - public void waitForSaveButtonDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$=':switch-to-view-mode-button']"), true); - } - - public void saveAndSwitchToViewMode() { - waitForElementDisplayed(By.cssSelector("[id$=':switch-to-view-mode-button']"), true); - click(By.cssSelector("[id$=':switch-to-view-mode-button']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void drapAndDropWidgets(String sourceName, String destinationName) { - waitForElementDisplayed(By.cssSelector(String.format("[id='case-details-%s-panel']", sourceName)), true); - WebElement sourceElement = findElementByCssSelector(String.format("[id='case-details-%s-panel']", sourceName)); - waitForElementDisplayed(By.cssSelector(String.format("[id='case-details-%s-panel']", destinationName)), true); - WebElement destinationElement = findElementByCssSelector(String.format("[id='case-details-%s-panel']", destinationName)); - Actions actions = new Actions(driver); - Action moveWidget = actions.dragAndDrop(sourceElement, destinationElement).build(); - moveWidget.perform(); - WaitHelper.assertTrueWithWait(() -> { - var caseDetails = findElementByCssSelector("[id$=':case-details-container:case-details-widgets']"); - return !caseDetails.getAttribute(CLASS_PROPERTY).contains("ui-droppable-over"); - }); - } - - public void waitForResetButtonDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-details-settings-button']"), true); - } - - public void waitForResetButtonNotPresent() { - waitForElementPresent(By.cssSelector("[id$=':reset-details-settings-button']"), false); - } - - public boolean hasDoneTask() { - List doneTasks = findListElementsByCssSelector(DONE_TASKS_SELECTOR); - return CollectionUtils.isNotEmpty(doneTasks); - } - - public boolean isRelatedTaskStartEnabled(String taskName) { - Integer index = getTaskRowIndex(taskName); - WebElement element = findListElementsByCssSelector("[id$='task-action-component']").get(index); - return !element.getAttribute(CLASS).contains("ui-state-disabled"); - } - - public TaskTemplatePage startRelatedTask(String taskName) { - Integer index = getTaskRowIndex(taskName); - WebElement element = findListElementsByCssSelector("[id$='task-action-component']").get(index); - element.click(); - return new TaskTemplatePage(); - } - - public void clickRelatedTaskActionButton(String taskName) { - Integer index = getTaskRowIndex(taskName); - clickByCssSelector(String.format("[id$=':related-tasks:%d:additional-options:task-side-steps-menu']", index)); - String actionPanel = String.format("[id$='task-widget:related-tasks:%d:additional-options:side-steps-panel']", index); - waitForElementDisplayed(By.cssSelector(actionPanel), true); - } - - public int getTaskRowIndexFromDetailPage(String taskName) { - List taskNames = findListElementsByCssSelector(".task-name-value"); - int taskIndex = IntStream.range(0, taskNames.size()).filter(i -> taskNames.get(i).getText().equals(taskName)).findFirst().getAsInt(); - return taskIndex; - } - - public void clickRelatedCaseActionButton(int index) { - WebElement element = findListElementsByCssSelector(".related-cases .more-column .action-link").get(index); - element.click(); - String actionPanel = String.format("[id$='related-cases-widget:related-cases:%d:action-step-component:action-steps-panel']", index); - waitForElementDisplayed(By.cssSelector(actionPanel), true); - } - - public void reserveTask(String taskName) { - Integer index = getTaskRowIndex(taskName); - String reserveCommandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-reserve-command']", index); - waitForElementDisplayed(By.cssSelector(reserveCommandButton), true); - findElementByCssSelector(reserveCommandButton).click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void resetTask(String taskName) { - Integer index = getTaskRowIndex(taskName); - String resetCommandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-reset-command", index); - waitForElementDisplayed(By.cssSelector(resetCommandButton), true); - findElementByCssSelector(resetCommandButton).click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public boolean isTaskState(String taskName, TaskBusinessState taskState) { - Integer index = getTaskRowIndex(taskName); - WebElement element = findListElementsByCssSelector("td.related-task-state-column span.task-state").get(index); - if(element!=null) { - String stateClass = element.getAttribute(CLASS); - return stateClass.contains(taskState.toString().toLowerCase()+"-task-state"); - } - return false; - } - - public boolean isRelatedTaskDestroyEnabled(String taskName) { - WebElement destroyButton = findDestroyCommand(taskName); - return !destroyButton.getAttribute(CLASS).contains("ui-state-disabled"); - } - - public void destroyTask(String taskName) { - findDestroyCommand(taskName).click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public WebElement findDestroyCommand(String taskName) { - Integer index = getTaskRowIndex(taskName); - String destroyCommandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-destroy-command", index); - waitForElementDisplayed(By.cssSelector(destroyCommandButton), true); - return findElementByCssSelector(destroyCommandButton); - } - - public void confimRelatedTaskDestruction() { - String destroyCaseDialogId = "[id$='task-widget:destroy-task-confirmation-dialog']"; - waitForElementDisplayed(By.cssSelector(destroyCaseDialogId), true); - WebElement destroyConfirmationDialog = findElementByCssSelector(destroyCaseDialogId); - WebElement confirmButton = findChildElementByCssSelector(destroyConfirmationDialog, "[id$='task-widget:confirm-destruction']"); - confirmButton.click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public String getResponsibleOfRelatedTaskAt(String taskName) { - List taskRows = findListElementsByCssSelector("tr.ui-widget-content"); - return taskRows.stream() - .filter(row -> findChildElementByCssSelector(row, ".task-name-value").getText().equals(taskName)) - .map(row -> findChildElementByCssSelector(row, ".name-after-avatar").getText()).findAny().get(); - } - - public void openTaskDelegateDialog(String taskName) { - try { - clickRelatedTaskActionButton(taskName); - } catch (Exception e) { - clickRelatedTaskActionButton(taskName); - } - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector("a[id$='\\:task-delegate-command']").isDisplayed()); - clickByCssSelector("a[id$='\\:task-delegate-command']"); - waitForElementDisplayed(By.cssSelector("div[id$='task-delegate-dialog']"), true); - } - - public boolean isDelegateTypeSelectAvailable() { - return isElementPresent(By.cssSelector("div[id$=':activator-panel']")); - } - - public void selectDelegateResponsible(String responsibleName, boolean isRole) { - if (isRole) { - waitForElementDisplayed(By.cssSelector("[id$=':task-delegate-form:activator-type-select']"), true); - waitForElementEnabled(By.cssSelector("[id$=':task-delegate-form:activator-type-select:1']"), true, DEFAULT_TIMEOUT); - clickByCssSelector("[for$=':task-delegate-form:activator-type-select:1']"); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - waitForElementDisplayed(By.cssSelector("input[id$='group-activator-select_input']"), true); - type(By.cssSelector("input[id$='group-activator-select_input']"), responsibleName); - waitForElementDisplayed(By.cssSelector("span[id$='group-activator-select_panel']"), true); - List foundRoles = - findListElementsByCssSelector("span[id$='group-activator-select_panel'] .name-after-avatar"); - foundRoles.get(0).click(); - } else { - waitForElementDisplayed(By.cssSelector("input[id$='user-activator-select_input']"), true); - type(By.cssSelector("input[id$='user-activator-select_input']"), responsibleName); - waitForElementDisplayed(By.cssSelector("span[id$='user-activator-select_panel']"), true); - List foundUsers = - findListElementsByCssSelector("span[id$='user-activator-select_panel'] .name-after-avatar"); - foundUsers.get(0).click(); - } - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - click(By.cssSelector("button[id$='proceed-task-delegate-command']")); - waitForElementDisplayed(By.cssSelector("div[id$='task-delegate-dialog']"), false); - } - - public boolean isTaskDelegateOptionDisable(String taskName) { - clickRelatedTaskActionButton(taskName); - Integer index= getTaskRowIndex(taskName); - String commandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-delegate-command", index); - waitForElementDisplayed(By.cssSelector(commandButton), true); - WebElement delegateButton = findElementByCssSelector(commandButton); - return delegateButton.getAttribute(CLASS).contains("ui-state-disabled"); - } - - public void openRelatedTaskWorkflowEvents(int index) { - String commandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-workflow-event-command", index); - waitForElementDisplayed(By.cssSelector(commandButton), true); - findElementByCssSelector(commandButton).click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public boolean isRelatedTaskWorkflowEventsOpened() { - try { - waitForElementDisplayed(By.cssSelector("div[id$='task-widget:workflow-event-component:workflow-events-dialog']"), true); - return true; - } catch (Exception e) { - return false; - } - } - - public ExpressProcessPage addAdHocTask(int index) { - String commandButton = String.format("[id$='task-widget:related-tasks:%d:additional-options:task-additional-actions']", index); - waitForElementDisplayed(By.cssSelector(commandButton), true); - findElementByCssSelector(commandButton).click(); - return new ExpressProcessPage(); - } - - public WebElement getExportToExcelLink(String linkId) { - return findElementByCssSelector("a[id$=':" + linkId + "']"); - } - - public void clickExportToExcelLink(String linkId, String statusDialogId) { - // Ensure that attribute is removed before downloading - JavascriptExecutor js = (JavascriptExecutor) driver; - WebElement statusDialog = driver.findElement(By.cssSelector("div[id$=':" + statusDialogId + "']")); - js.executeScript("arguments[0].removeAttribute('download-status')", statusDialog); - - // click download - WebElement downloadLink = getExportToExcelLink(linkId); - if (downloadLink != null) { - downloadLink.click(); - } - } - - public boolean isDownloadCompleted(String statusDialogId) { - WebElement statusDialog = driver.findElement(By.cssSelector("div[id$=':" + statusDialogId + "']")); - WaitHelper.assertTrueWithWait(() -> StringUtils.isNotBlank(statusDialog.getAttribute("download-status"))); - return StringUtils.equals(statusDialog.getAttribute("download-status"), "completed"); - } - - public boolean isRelatedCaseListColumnExist(String columnClass) { - WebElement column = findElementByCssSelector(".related-cases-container th." + columnClass); - return column != null && column.isDisplayed(); - } - - public void clickRelatedCaseColumnsButton() { - clickByCssSelector("a[id$='case-config-button']"); - waitForElementDisplayedByCssSelector("label[for$='related-cases-widget:case-columns-configuration:select-columns-form:columns-checkbox:3']"); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void clickRelatedCaseColumnCheckbox(int columnIndex) { - WebElement columnCheckbox = findElementByXpath(String.format("//*[contains(@id,\":related-cases-widget:case-columns-configuration:select-columns-form:columns-checkbox\")]/tbody/tr[%s]/td/div/div[2]", columnIndex));//findElementByCssSelector(String.format("input[id$='related-cases-widget:case-columns-configuration:select-columns-form:columns-checkbox:%d']", columnIndex)); - columnCheckbox.click(); - } - - public void clickRelatedCaseDefaultCheckbox() { - WebElement columnCheckbox = findElementByXpath("//*[contains(@id,\":related-cases-widget:case-columns-configuration:select-columns-form:default-columns\")]/div[2]");//findElementByCssSelector("input[id$='related-cases-widget:case-columns-configuration:select-columns-form:default-columns_input']"); - columnCheckbox.click(); - WaitHelper.assertTrueWithWait(() -> !findElementByCssSelector("label[for$='related-cases-widget:case-columns-configuration:select-columns-form:columns-checkbox:3']").getAttribute("class").equals("ui-state-disabled")); - } - - public void clickRelatedCaseApplyButton() { - click(By.cssSelector("button[id$='related-cases-widget:case-columns-configuration:select-columns-form:update-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public boolean isRelatedTaskListColumnExist(String columnClass) { - WebElement column = findElementByCssSelector(".case-details-related-task-table th." + columnClass); - return column != null && column.isDisplayed(); - } - - public void clickRelatedTaskColumnsButton() { - clickByCssSelector("a[id$='task-config-command']"); - waitForElementDisplayedByCssSelector("label[for$='task-widget:task-columns-configuration:select-columns-form:columns-checkbox:5']"); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void clickRelatedTaskColumnCheckbox(int columnIndex) { - WebElement columnCheckbox = findElementByXpath(String.format("//*[contains(@id,\":task-widget:task-columns-configuration:select-columns-form:columns-checkbox\")]/tbody/tr[%s]/td/div/div[2]", columnIndex));//findElementByCssSelector(String.format("input[id$='related-cases-widget:case-columns-configuration:select-columns-form:columns-checkbox:%d']", columnIndex)); - columnCheckbox.click(); - } - - public void clickRelatedTaskDefaultCheckbox() { - WebElement columnCheckbox = findElementByXpath("//*[contains(@id,\":task-widget:task-columns-configuration:select-columns-form:default-columns\")]/div[2]");//findElementByCssSelector("input[id$='related-cases-widget:case-columns-configuration:select-columns-form:default-columns_input']"); - columnCheckbox.click(); - WaitHelper.assertTrueWithWait(() -> !findElementByCssSelector("label[for$='task-widget:task-columns-configuration:select-columns-form:columns-checkbox:5']").getAttribute("class").equals("ui-state-disabled")); - } - - public void clickRelatedTaskApplyButton() { - click(By.cssSelector("button[id$='task-widget:task-columns-configuration:select-columns-form:update-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public boolean iframeCustomWidgetIsDisplayed() { - return findElementByCssSelector("iframe[name='custom-widget-iframe']").isDisplayed(); - } - - public String getProcessLinkInCustomIFrameWidget() { - WebElement formInFrame = findElementByCssSelector("form[id='custom-widget-iframe-data']"); - return formInFrame.getAttribute("action"); - } - - public String getIFrameURLOfCustomWidget() { - WebElement iframe = findElementByCssSelector("[id$=':custom-iframe']"); - return iframe.findElement(By.tagName("iframe")).getAttribute("src"); - } - - public boolean isCustomMiddlePanelDisplay() { - return findElementByCssSelector("[id$=':caseItemDetailCustomMiddle']").isDisplayed(); - } - - public void waitForIFrameWidgetLoad() { - driver.switchTo().frame("custom-widget-iframe"); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("form[id='content-form']").isDisplayed()); - } - - public void waitForIFrameURLWidgetLoad() { - driver.switchTo().frame("custom-widget-iframe-url"); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("a[href='https://www.axonivy.com']").isDisplayed()); - } - - public void openActionMenu() { - clickByCssSelector("[id$=':action-group:case-details-action-link']"); - waitForElementDisplayed(By.cssSelector("[id$=':action-group:action-steps-panel'].action-steps-panel"), true); - } - - public List getAvailableActionSteps() { - waitForElementDisplayed(By.cssSelector("[id$=':action-group:action-steps-panel'].action-steps-panel"), true); - var steps = findListElementsByCssSelector("[id$=':action-group:action-steps-panel'].action-steps-panel a.action-step-item"); - return steps.stream().map(WebElement::getText).collect(Collectors.toList()); - } - - public String getEventTypeInWorkflowEvents(){ - waitForElementDisplayed(By.cssSelector("[id$=':task-widget:workflow-event-component:events-table_data']"), true); - var eventTypeList = findElementByCssSelector("[id$=':task-widget:workflow-event-component:events-table_data']").getText(); - return eventTypeList; - } - - public List getAvailableActionStepsOfTechnicalCase(int caseIndex) { - var panelId = String.format("[id$=':related-cases-widget:related-cases:%d:action-step-component:action-steps-panel']", caseIndex); - waitForElementDisplayed(By.cssSelector(panelId), true); - var steps = findListElementsByCssSelector(panelId + " a.action-step-item"); - return steps.stream().map(WebElement::getText).collect(Collectors.toList()); - } - - public int getNumberOfHistoryForRelatedCaseLink() { - waitForElementDisplayed(By.cssSelector("[id$=':case-histories:case-histories']"), true); - return findListElementsByCssSelector("td.history-related-case a[id$=':related-case-link']").size(); - } - - public String getContentOfHistoryTableRelatedCaseColumn(int rowIndex) { - waitForElementDisplayed(By.cssSelector("[id$=':case-histories:case-histories']"), true); - return findElementByCssSelector(String - .format("td.history-related-case a[id$='case-histories:%d:related-case-link']", rowIndex)) - .getText(); - } - - public boolean isShowRelatedCaseCheckbox() { - waitForElementDisplayed(By.cssSelector("[id$=':history-container']"), true); - try { - return findElementByCssSelector("[id$=':case-histories:related-case-checkbox']").isDisplayed(); - } catch (Exception e) { - return false; - } - } - - public void clickOnRelatedCaseCheckbox(boolean checkboxShouldBeChecked) { - waitForElementDisplayed(By.cssSelector("[id$=':history-container']"), true); - var relatedCaseCheckbox = findElementByCssSelector("[id$=':case-histories:related-case-checkbox']"); - var checkbox = relatedCaseCheckbox.findElement(By.cssSelector("div.ui-chkbox-box.ui-widget")); - if ((checkboxShouldBeChecked && checkbox.getAttribute(CLASS).contains("ui-state-active")) - || (!checkboxShouldBeChecked && !checkbox.getAttribute(CLASS).contains("ui-state-active"))) { - return; - } else { - click(relatedCaseCheckbox.findElement(By.cssSelector("span.ui-chkbox-label"))); - // Cannot identify when the ajax request of select checkbox is finished - // So we need to wait for Ajax Indicator disappear - waitAjaxIndicatorDisappear(); - clickOnRelatedCaseCheckbox(checkboxShouldBeChecked); - } - } - - public boolean isRelatedCaseInfoColumnIsDisplay() { - waitForElementDisplayed(By.cssSelector("[id$=':history-container']"), true); - try { - return findElementByCssSelector("[id$=':case-histories'] th.history-related-case").isDisplayed(); - } catch (Exception e) { - return false; - } - } - - public Integer getTaskRowIndex(String taskName) { - List taskNames = findListElementsByCssSelector(".task-name-value"); - int taskIndex = IntStream.range(0, taskNames.size()).filter(i -> taskNames.get(i).getText().equals(taskName)).findFirst().getAsInt(); - return taskIndex; - } - - public WebElement getSharePageButtonElement() { - return findElementByCssSelector("[id$=':share-page-button']"); - } - - public String getCaseUuid() { - return findElementByCssSelector("a[id$='show-more-note-link']").getAttribute("href").split("uuid=")[1]; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseWidgetPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseWidgetPage.java deleted file mode 100644 index adc3829f5ea..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/CaseWidgetPage.java +++ /dev/null @@ -1,483 +0,0 @@ -package portal.guitest.page; - -import static portal.guitest.common.WaitHelper.assertTrueWithWait; - -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; -import com.jayway.awaitility.core.ConditionTimeoutException; - -import portal.guitest.common.CaseState; -import portal.guitest.common.WaitHelper; - -public class CaseWidgetPage extends TemplatePage { - - private String caseWidgetId; - private static final String CASE_ITEM_LIST_SELECTOR = "li[class='ui-datascroller-item']"; - private static final String CASE_NAME_CSS_SELECTOR = "span[class*='case-header-name-cell']"; - private static final String CASE_PAGE_LOCATION = "//*[contains(@id,'case-view')]"; - private static final String SELECT_COLUMNS_LINK_CSS_SELECTOR = "a[id$='case-config-button']"; - private static final String SELECT_ITEM_XPATH = - "//*[@id=\"case-widget:case-columns-configuration:select-columns-form:columns-checkbox\"]/tbody/tr[%s]/td/div/div[2]"; - private static final String APPLY_BUTTON_CSS_SELECTOR = "button[id$='select-columns-form:update-command']"; - private static final String DEFAULT_COLUMNS_XPATH = - "//*[@id=\"case-widget:case-columns-configuration:select-columns-form:default-columns\"]/div[2]"; - - public CaseWidgetPage() { - this("case-widget"); - } - - public CaseWidgetPage(String caseWidgetId) { - this.caseWidgetId = caseWidgetId; - } - - @Override - protected String getLoadedLocator() { - return CASE_PAGE_LOCATION; - } - - public int countSideStepItems() { - WebElement actionsPanel = getMoreActionsPanel(); - return actionsPanel.findElements(By.cssSelector("a[id$='side-step-item']")).size(); - } - - public WebElement selectCaseItem(int index) { - String caseItemId = String.format(caseWidgetId + ":case-list-scroller:%s:case-item", index); - return findElementById(caseItemId); - } - - private WebElement getDestroyButtonOfCaseItem() { - openActionStepMenu(); - waitForElementDisplayed(By.cssSelector("a[id$='destroy-case']"), true); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector("a[id$='destroy-case']").isDisplayed()); - return findElementByCssSelector("a[id$='destroy-case']"); - } - - public void openActionStepMenu() { - waitForElementDisplayed(By.cssSelector("[id$=':case-item:case-item-action-form']"), true); - clickByCssSelector("a[id$='action-steps-menu']"); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void openAdditionalCaseDetails() { - waitForElementDisplayed(By.cssSelector("[id$=':show-additional-case-details-link']"), true); - clickByCssSelector("[id$=':show-additional-case-details-link']"); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - private WebElement getMoreActionsPanel() { - openActionStepMenu(); - waitForElementDisplayed(By.cssSelector("div[id$='action-steps-panel']"), true); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector("div[id$='action-steps-panel']").isDisplayed()); - return findElementByCssSelector("div[id$='action-steps-panel']"); - } - - public void clickDestroyButton() { - WebElement destroyButton = getDestroyButtonOfCaseItem(); - destroyButton.click(); - } - - public boolean isDestroyButtonVisible() { - try { - openActionStepMenu(); - waitForElementDisplayed(By.cssSelector("div[id$='action-steps-panel']"), true); - return isElementDisplayed(By.cssSelector("a[id$='destroy-case'")); - } catch (Exception ex) { - return false; - } - } - - public void confimDestruction() { - String destroyCaseDialogId = caseWidgetId + ":destroy-case-confirmation-dialog"; - waitForElementDisplayed(By.id(destroyCaseDialogId), true); - WebElement destroyConfirmationDialog = findElementById(destroyCaseDialogId); - WebElement confirmButton = findChildElementById(destroyConfirmationDialog, caseWidgetId + ":confirm-destruction"); - confirmButton.click(); - } - - public CaseDetailsPage openDetailsOfCaseHasName(String caseName) { - List caseItems = findListElementsByCssSelector(CASE_ITEM_LIST_SELECTOR); - for (WebElement caseItem : caseItems) { - if (caseItem.findElement(By.cssSelector(CASE_NAME_CSS_SELECTOR)).getText().equals(caseName)) { - caseItem.findElement(By.cssSelector("span[id*='case-info-row']")).click(); - return new CaseDetailsPage(); - } - } - throw new NoSuchElementException("Cannot find case has name " + caseName); - } - - public CaseDetailsPage openCaseDetailsFromActionMenuByCaseName(String caseName) { - List caseItems = findListElementsByCssSelector(CASE_ITEM_LIST_SELECTOR); - for (WebElement caseItem : caseItems) { - if (caseItem.findElement(By.cssSelector(CASE_NAME_CSS_SELECTOR)).getText().equals(caseName)) { - caseItem.findElement(By.cssSelector("a[id*='action-steps-menu']")).click(); - waitForElementDisplayed(By.cssSelector("div[id$='action-steps-panel']"), true); - findElementByCssSelector("a[id$='case-item-open-detail-link']").click(); - return new CaseDetailsPage(); - } - } - throw new NoSuchElementException("Cannot find case has name " + caseName); - } - - public int getNumberOfCases() { - List caseItems = findListElementsByCssSelector(CASE_ITEM_LIST_SELECTOR); - return caseItems.size(); - } - - public String getCaseNameAt(int index) { - waitForElementDisplayed(By.className("js-case-list"), true); - WebElement name = findElementByCssSelector("[id$='case-list-scroller:" + index + ":case-item:case-name-component:case-header-name-cell']"); - return name.getText(); - } - - public String getCreatorAt(int index) { - List creators = findListElementsByCssSelector(".case-header-creator-cell .name-after-avatar"); - return creators.get(index).getText(); - } - - public String getCaseName() { - waitForElementDisplayed(By.cssSelector("*[id$='case-list']"), true); - WebElement selectedCaseElement = findElementByCssSelector(".case-list-item-expanded"); - WebElement selectedCaseNameElement = findElementById( - selectedCaseElement.getAttribute("id") + ":case-name-component:case-name-form:case-name-edit-inplace"); - return selectedCaseNameElement.getText(); - } - - public String getCaseId() { - waitForElementDisplayed(By.cssSelector("*[id$=':case-list']"), true); - WebElement selectedCaseElement = findElementByCssSelector(".case-list-item-expanded"); - WebElement selectedCaseIdElement = selectedCaseElement.findElement(By.cssSelector(".case-header-id-cell")); - return selectedCaseIdElement.getText(); - } - - public String getCaseId(int caseIndex) { - waitForElementDisplayed(By.cssSelector("*[id$=':case-list']"), true); - WebElement selectedCaseElement = findElementByCssSelector(String.format("[id$='case-list-scroller:%d:case-item:case-item-container']", caseIndex)); - WebElement selectedCaseIdElement = selectedCaseElement.findElement(By.cssSelector("[id$=':case-id-cell']")); - return selectedCaseIdElement.getText(); - } - - public boolean isCaseDisplayed(String name) { - waitForElementDisplayed(By.cssSelector("div[id='case-widget:case-list-scroller']"), true); - List caseNameElements = findListElementsByClassName("case-header-name-cell"); - return caseNameElements.stream().anyMatch(caseNameElement -> name.equals(caseNameElement.getText())); - } - - public boolean isCaseListColumnExist(String columnHeaderText) { - WebElement taskListHeader = findElementById(caseWidgetId + ":widget-column-header"); - for (WebElement column : taskListHeader.findElements(By.tagName("a"))) { - if (columnHeaderText.equals(column.getText())) { - return true; - } - } - return false; - } - - @SuppressWarnings("deprecation") - public void openAdvancedFilter(String filterName, String filterIdName) { - click(By.id(caseWidgetId + ":filter-add-action")); - waitForElementDisplayed(By.cssSelector(".filter-add-panel.ui-connected-overlay-enter-done"), true); - waitForElementDisplayed(By.cssSelector("[id$='" + caseWidgetId + ":filter-add-form:filter-selection']"), true); - WebElement filterSelectionElement = findElementById(caseWidgetId + ":filter-add-form:filter-selection"); - - System.out.println(filterSelectionElement.getTagName()); - List elements = findChildElementsByTagName(filterSelectionElement, "LABEL"); - for (WebElement element : elements) { - if (element.getText().equals(filterName)) { - element.click(); - click(findElementById("case-widget:filter-add-form:update-filter-selected-command")); - waitAjaxIndicatorDisappear(); - break; - } - } - waitForElementDisplayed( - By.cssSelector("span[id$='" + filterIdName + "-filter:filter-open-form:advanced-filter-item-container']"), - true); - } - - @SuppressWarnings("deprecation") - public void filterByDescription(String text) { - click(By.cssSelector("button[id$='description-filter:filter-open-form:advanced-filter-command']")); - WebElement descriptionInput = - findElementByCssSelector("input[id$='description-filter:filter-input-form:description']"); - enterKeys(descriptionInput, text); - click(By.cssSelector("button[id$='description-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void saveFilter(String filterName) { - getSaveFilterDialog(); - WebElement filterNameInput = findElementById(caseWidgetId + ":filter-save-form:save-filter-set-name-input"); - enterKeys(filterNameInput, filterName); - click(findElementById(caseWidgetId + ":filter-save-form:filter-save-command")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - public WebElement getSaveFilterDialog() { - click(By.id(caseWidgetId + ":filter-save-action")); - var filterId = caseWidgetId + ":filter-save-action"; - clickByCssSelector("[id$='" + filterId + "']"); - waitForElementDisplayed(By.id(caseWidgetId + ":filter-save-form:save-filter-set-name-input"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, caseWidgetId + "\\\\:filter-save-form\\\\:save-filter-set-name-input", ID_PROPERTY); - return findElementById(caseWidgetId + ":save-filter-set-dialog"); - } - - public String getFilterName() { - WebElement filterName = findElementByCssSelector("[id$='case-widget:filter-selection-form:filter-name'] > span"); - return filterName.getText(); - } - - public String getFilterValue(String filterId) { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until( - () -> findElementByCssSelector("button[id$='" + filterId + ":filter-open-form:advanced-filter-command']") - .getText().length()>1); - waitForElementDisplayed(By.cssSelector("button[id$='" + filterId + ":filter-open-form:advanced-filter-command']"), true); - WebElement filterElement = - findElementByCssSelector("button[id$='" + filterId + ":filter-open-form:advanced-filter-command']"); - return filterElement.getText(); - } - - public boolean isEmpty() { - return isElementDisplayed(By.id("search-results-tabview:case-results:case-empty-message")); - } - - public void sortCaseListByColumn(String columnId) { - WebElement columnHeader = findElementById(columnId); - columnHeader.click(); - WaitHelper.assertTrueWithWait(() -> { - return findElementById(columnId).getAttribute(CLASS_PROPERTY).contains("is-selected"); - }); - } - - public String getSelectedSortColumn() { - waitForElementDisplayed(By.cssSelector(".js-case-widget-column-header"), true); - return findElementByCssSelector(".js-case-widget-column-header a.ui-commandlink.is-selected").getText(); - } - - public String getCaseListFirstCustomCellValue() { - return findElementByCssSelector("div[id$=':0\\:case-item\\:case-item-container'] span.customized-case-header-column").getText(); - } - - public Integer getCaseCount() { - String title = getTextOfCurrentBreadcrumb(); - String count = StringUtils.substringBetween(title, "(", ")"); - return StringUtils.isNotBlank(count) ? Integer.parseInt(count) : null; - } - - /** - * count number of case row - * @return number of case elements - */ - public int countCases() { - List caseItems = findListElementsByCssSelector("div[class*='case-list-item']"); - return caseItems.size(); - } - - public void waitUntilCaseCountDifferentThanZero() { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> getCaseCount().intValue() != 0); - } - - public void clickColumnsButton() { - clickByCssSelector(SELECT_COLUMNS_LINK_CSS_SELECTOR); - waitForElementDisplayedByCssSelector("label[for$='columns-checkbox:3']"); - } - - public void clickColumnCheckbox(int columnIndex) { - WebElement columnCheckbox = findElementByXpath(String.format(SELECT_ITEM_XPATH, columnIndex)); - click(columnCheckbox); - } - - public void clickColumnCheckboxByName(String columnName) { - waitForElementDisplayed(By.cssSelector("[id$=':case-columns-configuration:case-config-columns-panel']"), true); - findListElementsByCssSelector("label[for*=':case-columns-configuration:select-columns-form:columns-checkbox:']").stream() - .filter(checkbox -> checkbox.getText().equalsIgnoreCase(columnName)).findAny() - .ifPresent(foundCheckbox -> { - clickByJavaScript(foundCheckbox); - }); - } - - public void clickDefaultCheckbox() { - WebElement columnCheckbox = findElementByXpath(DEFAULT_COLUMNS_XPATH); - click(columnCheckbox); - WaitHelper.assertTrueWithWait(() -> !findElementByCssSelector("label[for$='columns-checkbox:3']").getAttribute("class").equals("ui-state-disabled")); - } - - @SuppressWarnings("deprecation") - public void clickApplyButton() { - click(By.cssSelector(APPLY_BUTTON_CSS_SELECTOR)); - waitAjaxIndicatorDisappear(); - } - - public boolean isLoadingCategories() { - return isElementDisplayed(By.cssSelector(".loading-panel")); - } - - public boolean isAllCategoriesSelected() { - waitForElementDisplayed(By.cssSelector(".filter-category-checkbox-tree"), true); - return isElementDisplayed(By.cssSelector(".filter-category-checkbox-tree .ui-treenode-selected")); - } - - public boolean isAllCategoriesUnselected() { - waitForElementDisplayed(By.cssSelector(".filter-category-checkbox-tree"), true); - return isElementDisplayed(By.cssSelector(".filter-category-checkbox-tree .ui-treenode-hasselected")); - } - - public void openCategoryFilter() { - click(By.cssSelector("button[id$='case-category-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("div[id$=':case-category-filter-tree']"), true); - } - - public void toggleNoCategory() { - List categories = findListElementsByCssSelector(".filter-category-checkbox-tree .ui-tree-selectable"); - for (WebElement category : categories) { - if (category.getText().equals("[No Category]")) { - click(category); - return; - } - } - } - - public void applyCategoryFilter() { - click(By.cssSelector("button[id$='case-category-filter:filter-input-form:update-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void filterByCreator(String text) { - click(By.cssSelector("button[id$='creator-filter:filter-open-form:advanced-filter-command']")); - WebElement responsible = findElementByCssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']"); - type(responsible, text); - waitAjaxIndicatorDisappear(); - waitForElementDisplayedByCssSelector("div[id*='creator-filter'] .ui-avatar-text"); - click(By.cssSelector("div[id*='creator-filter'] .ui-avatar-text")); - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='creator-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public boolean isUserDisplayInCreatorFilter(String userFullName) { - click(By.cssSelector("button[id$='creator-filter:filter-open-form:advanced-filter-command']")); - WebElement responsible = - findElementByCssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']"); - type(responsible,userFullName); - waitAjaxIndicatorDisappear(); - try { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector("span[id$='filter-input-form:creator-component:creator-select_panel']").isDisplayed()); - } - catch(ConditionTimeoutException timeoutException) { - return false; - } - return true; - } - - public void openSavedFilters(String filterName) { - refreshAndWaitElement("a[id$='case-widget:filter-selection-form:filter-name']"); - click(findElementById("case-widget:filter-selection-form:filter-name")); - waitForElementDisplayed(By.cssSelector(".filter-name-overlay-panel.ui-connected-overlay-enter-done"), true); - List saveFilters = findListElementsByCssSelector("a[id$='user-defined-filter']"); - for (WebElement filter : saveFilters) { - if (filter.getText().equals(filterName)) { - click(filter); - assertTrueWithWait(() -> findElementByCssSelector(".filter-name").getText().equals(filterName)); - return; - } - } - } - - @SuppressWarnings("deprecation") - public void removeResponsibleFilter() { - click(By.cssSelector("button[id$='creator-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']"), true); - findElementByCssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']").clear(); - click(By.cssSelector("button[id$='creator-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - public String getCreator() { - refreshAndWaitElement("button[id$='creator-filter:filter-open-form:advanced-filter-command']"); - click(By.cssSelector("button[id$='creator-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']"),true); - return findElementByCssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']") - .getAttribute("value"); - } - - public void waitUntilCaseFilterDisplayed() { - waitForElementDisplayed(By.id("case-widget:filter-container"), true); - } - - public CaseState getCaseState(int caseIndex) { - List caseStateCells = findListElementsByCssSelector("span[id$=':case-state-cell']"); - String stateClass = caseStateCells.get(caseIndex).findElement(By.className("case-state")).getAttribute("class"); - String[] stateClasses = stateClass.trim().split(" "); - String state = Stream.of(stateClasses).filter(clazz -> clazz.endsWith("-case-state")).findFirst().orElse(""); - return CaseState.fromClass(state); - } - - @SuppressWarnings("deprecation") - public void filterByOwner(String text) { - click(By.cssSelector("button[id$='owner-filter:filter-open-form:advanced-filter-command']")); - WebElement owner = findElementByCssSelector("input[id$='owner-filter:filter-input-form:owner_input']"); - type(owner, text); - waitAjaxIndicatorDisappear(); - waitForElementDisplayedByCssSelector("div[id*='owner-filter'] .ui-avatar-text"); - click(By.cssSelector("div[id*='owner-filter'] .ui-avatar-text")); - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='owner-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - public WebElement getExportToExcelLink() { - return findElementByCssSelector("a[id$=':case-export-to-excel']"); - } - - public void clickExportToExcelLink() { - // Ensure that attribute is removed before downloading - JavascriptExecutor js = (JavascriptExecutor) driver; - WebElement statusDialog = driver.findElement(By.cssSelector("div[id$=':status-dialog']")); - js.executeScript("arguments[0].removeAttribute('download-status')", statusDialog); - - // click download - WebElement downloadLink = getExportToExcelLink(); - if (downloadLink != null) { - downloadLink.click(); - } - } - - public boolean isDownloadCompleted() { - WebElement statusDialog = driver.findElement(By.cssSelector("div[id$=':status-dialog']")); - WaitHelper.assertTrueWithWait(() -> StringUtils.isNotBlank(statusDialog.getAttribute("download-status"))); - return StringUtils.equals(statusDialog.getAttribute("download-status"), "completed"); - } - - public boolean isCategoryColumnDisplayed() { - return findElementByCssSelector("span[id$=':case-category-cell']").isDisplayed(); - } - - public List getAvailableActionSteps() { - waitForElementDisplayed(By.cssSelector("[id$=':action-steps-panel']"), true); - var steps = findListElementsByCssSelector("[id$=':action-steps-panel'] a.action-step-item"); - return steps.stream().map(WebElement::getText).collect(Collectors.toList()); - } - - public void clickOnProcessViewerOption() { - waitForElementDisplayed(By.cssSelector("[id$=':action-steps-panel']"), true); - clickByCssSelector("a[id$=':case-item:case-item-action-form:action-step-component:show-process-viewer-link']"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChangePasswordPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChangePasswordPage.java deleted file mode 100644 index a5233f1224b..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChangePasswordPage.java +++ /dev/null @@ -1,56 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.WebElement; - -import portal.guitest.common.Sleeper; - -public class ChangePasswordPage extends TemplatePage { - - - @Override - protected String getLoadedLocator() { - return "id('change-password-dialog_title')"; - } - - @SuppressWarnings("deprecation") - public void changePassword(String currentPassword, String newPassword) { - inputCurrentPassword(currentPassword); - inputConfirmNewPassword(newPassword); - inputNewPassword(newPassword); - WebElement changeButton = findElementById("change-password-form:password-setting:save-password-setting"); - click(changeButton); - waitAjaxIndicatorDisappear(); - } - - private void inputCurrentPassword(String currentPassword) { - inputField("change-password-form:password-setting:current-password", currentPassword); - } - - private void inputNewPassword(String newPassword) { - inputField("change-password-form:password-setting:new-password", newPassword); - } - - private void inputConfirmNewPassword(String newPassword) { - inputField("change-password-form:password-setting:confirm-new-password", newPassword); - } - - private void inputField(String inputId, String value) { - WebElement inputField = findElementById(inputId); - inputField.sendKeys(value); - } - - public boolean isWrongCurrentPasswordError() { - WebElement element = findElementByCssSelector("#change-password-form\\:password-setting\\:change-password-messages .ui-messages-error-detail"); - return element.getText().equalsIgnoreCase("Authentication failed, your password seems to be wrong!"); - } - - public boolean isNewPasswordNotStrongEnough() { - WebElement element = findElementByCssSelector("#change-password-form\\:password-setting\\:change-password-messages .ui-messages-error-detail"); - return element.getText().equalsIgnoreCase("Password must be at least 4 characters long, contain at least 1 lowercase character, contain at least 1 uppercase character, contain at least 1 number, contain at least 1 special character."); - } - - public WebElement getChangePasswordDialog() { - Sleeper.sleep(200);//sleep a bit to make focus field effect before taking the screenshot - return findElementById("change-password-dialog"); - } -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChatPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChatPage.java deleted file mode 100644 index 214618c8c5f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ChatPage.java +++ /dev/null @@ -1,148 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.stream.Collectors; - -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; - -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class ChatPage extends TemplatePage { - - private static final String DIALOG_TITLE = "toggle-chat-panel-command"; - - public ChatPage() { - waitForElementDisplayed(By.id(DIALOG_TITLE), true); - } - - @Override - protected String getLoadedLocator() { - return "id('" + DIALOG_TITLE + "')"; - } - - @Override - public boolean isDisplayed() { - return findElementById(DIALOG_TITLE).isDisplayed(); - } - - public boolean isChatGroupDisplayed(String groupChatID) { - return findElementByXpath("//span[contains(text(),'" + groupChatID + "')]").isDisplayed(); - } - - public void selectChatUser(String name) { - waitForElementDisplayed(By.xpath("//span[text()='" + name + "']"), true); - click(findElementByXpath("//span[text()='" + name + "']")); - } - - public void sendMessage(String chatMessage) { - waitForElementExisted("textarea[id='message-input-field']", true, DEFAULT_TIMEOUT); - waitForElementEnabled(By.id("message-input-field"), true, DEFAULT_TIMEOUT); - WebElement input = findElementById("message-input-field"); - input.sendKeys(chatMessage); - input.sendKeys(Keys.ENTER); - WaitHelper.assertTrueWithWait(() -> getAllMessagesChatLog().contains(chatMessage)); - } - - public String getAllMessagesChatLog() { - waitForElementDisplayed(By.id("chat-message-list"), true, DEFAULT_TIMEOUT); - return findListElementsByClassName("js-message").stream().map(WebElement::getText).collect(Collectors.joining(",")); - } - - @SuppressWarnings("deprecation") - public void addUserToChatGroup(List responsibles) { - ensureNoBackgroundRequest(); - waitForElementDisplayed(By.id("chat-assignee-dialog"), true); - for (ExpressResponsible responsible : responsibles) { - chooseResponsible(responsible.getResponsibleName(), responsible.isGroup()); - } - } - - @SuppressWarnings("deprecation") - public void chooseResponsible(String responsible, boolean isGroup) { - if (isGroup) { - selectRoleAssigneeCheckbox(); - waitAjaxIndicatorDisappear(); - type(By.cssSelector("input[id$='selection_input']"), responsible); - waitForElementDisplayed(By.id("chat-assignee-selection-form:chat-role-selection-component:chat-role-selection_panel"), true); - click(By.cssSelector( - "span[id='chat-assignee-selection-form:chat-role-selection-component:chat-role-selection_panel'] .gravatar")); - } else { - type(By.cssSelector("input[id$='selection_input']"), responsible); - waitForElementDisplayed(By.cssSelector("span[id$='chat-user-selection_panel']"), true); - click(By.xpath( - "//*[@id='chat-assignee-selection-form:chat-user-selection-component:chat-user-selection_panel']/table/tbody/tr")); - } - waitForElementEnabled(By.id("chat-assignee-selection-form:chat-add-assignee-button"), true, 5); - click(By.id("chat-assignee-selection-form:chat-add-assignee-button")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - private void selectRoleAssigneeCheckbox() { - WebElement checkboxLabel = - findElementByXpath(String.format("//label[@for='%s']", "chat-assignee-selection-form:chat-assignee-type:1")); - click(checkboxLabel); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.cssSelector("input[id$='role-selection_input']"), true); - } - - @SuppressWarnings("deprecation") - public String getAllParticipants() { - waitForElementDisplayed(By.cssSelector("a[id$='show-participants-link']"), true); - click(By.cssSelector("a[id$='show-participants-link']")); - waitAjaxIndicatorDisappear(); - return GetUserParticipantsList() + "," + GetRolesParticipantsList(); - } - - private String GetUserParticipantsList() { - waitForElementDisplayed(By.id("participants-list-dialog"), true); - return findListElementsByCssSelector("ul[id='user-participants-list'] li").stream().map(WebElement::getText) - .collect(Collectors.joining(",")); - } - - private String GetRolesParticipantsList() { - waitForElementDisplayed(By.id("participants-list-dialog"), true); - return findListElementsByCssSelector("ul[id='roles-participants-list'] li ul li").stream().map(WebElement::getText) - .collect(Collectors.joining(",")); - } - - public void closeModalParticipants() { - waitForElementDisplayed(By.xpath("//div[@id='participants-list-dialog']//span[contains(text(),'Close')]"), true); - click(By.xpath("//div[@id='participants-list-dialog']//span[contains(text(),'Close')]")); - } - - public void closeChatMessageList() { - waitForElementDisplayed(By.cssSelector(".js-close-message-list"), true); - click(By.cssSelector(".js-close-message-list")); - } - - public boolean isNotificationBadgeChat() { - waitForElementDisplayed(By.cssSelector("a.notification-badge"), true); - return isElementPresent(By.cssSelector("a[data-badge=' ']")); - } - - public boolean isNotificationContactChat() { - return isElementPresent(By.cssSelector("span[class$='js-notification']")); - } - - public void openFirstGroupChat() { - waitForElementDisplayed(By.id("chat-form:group-chat-container"), true); - List chatGroups = findListElementsByClassName("js-group-card-name"); - if(!chatGroups.isEmpty()) { - click(chatGroups.get(0)); - } - Sleeper.sleep(300);//Wait for animation finish to capture screenshot - } - - public int refreshAndCountGroupChat() { - refresh(); - getChat(); - waitForElementDisplayed(By.id("chat-form:group-chat-container"), true); - List chatGroups = findChildElementsByClassName(findElementById("chat-form:group-chat-container"), "js-group-card-name"); - return chatGroups.size(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardConfigurationPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardConfigurationPage.java deleted file mode 100644 index 801986d8123..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardConfigurationPage.java +++ /dev/null @@ -1,199 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.FileHelper; - -public class DashboardConfigurationPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('configuration-group')"; - } - - public void configureDashboardByIndex(int index) { - String configIconId = String.format("[id$=':dashboard-table:%d:configure-dashboard']", index); - clickByCssSelector(configIconId); - } - - public void selectPublicDashboardType() { - waitForElementDisplayed(By.cssSelector("[id$='dashboard-configuration-type']"), true); - clickByCssSelector("a[id$='public-dashboard-type']"); - waitForElementPresent(By.cssSelector(".dashboard-configuration__content.js-public-dashboard-configuration"), true); - } - - public void selectPrivateDashboardType() { - waitForElementDisplayed(By.cssSelector("[id$='dashboard-configuration-type']"), true); - clickByCssSelector("a[id$='private-dashboard-type']"); - waitForElementPresent(By.cssSelector(".dashboard-configuration__content.js-private-dashboard-configuration"), true); - } - - public void selectEditPublicDashboards() { - waitForElementDisplayed(By.cssSelector(".dashboard-configuration__content.js-public-dashboard-configuration"), true); - clickByCssSelector("button[id$='dashboard-modification-component:dashboard-table:0:configure-dashboard']"); - } - - public WebElement getDashboardConfigurationPage() { - return findElementById("configuration-group"); - } - public WebElement getPublicConfigurationContent() { - return findElementByCssSelector(".dashboard-configuration__content.js-public-dashboard-configuration"); - } - - public WebElement getPrivateConfigurationContent() { - return findElementByCssSelector(".dashboard-configuration__content.js-private-dashboard-configuration"); - } - - public void createPrivateDashboardFromScratch() { - createPrivateDashboard(); - clickByCssSelector("a[id$=':create-from-scratch']"); - waitForElementDisplayed(By.cssSelector("div[id$=':dashboard-creation-details-dialog']"), true); - findElementByCssSelector("[id$=':dashboard-title']").sendKeys("My dashboard"); - } - - public void createPrivateDashboard() { - selectPrivateDashboardType(); - clickByCssSelector("button[id$='create-dashboard-action']"); - waitForElementDisplayed(By.cssSelector("div[id$=':create-new-dashboard-section']"), true); - } - - public void cancelCreateDashboard() { - clickByCssSelector("a[id$='dashboard-creation-component:dashboard-detail-close-button']"); - } - - public void clickOkCreateDashboard() { - clickByCssSelector("button[id$='dashboard-creation-component:dashboard-create-button']"); - } - - public void openEditPrivateDashboards() { - selectPrivateDashboardType(); - clickByCssSelector("a[id$='edit-dashboard-action'].js-private-dashboard"); - waitForElementDisplayed(By.cssSelector("[id$='dashboard-modification-container']"), true); - } - - public void closeAddDashboardDialog() { - waitForElementDisplayed(By.cssSelector("[id='dashboard-template-selection-component:create-new-dashboard-dialog']"), true); - WebElement element = findElementByCssSelector("[id='dashboard-template-selection-component:create-new-dashboard-dialog']"); - waitAjaxIndicatorDisappear(); - element.findElement(By.cssSelector("a.ui-dialog-titlebar-close")).click(); - } - - public void reorderPrivateDashboards() { - selectPrivateDashboardType(); - clickByCssSelector("a[id$='reorder-dashboard-action'].js-private-dashboard"); - waitForElementDisplayed(By.cssSelector("[id$='reorder-dashboard-form:dashboard-table']"), true); - } - - public void createPublicDashboardFromScratch() { - selectPublicDashboardType(); - clickByCssSelector("button[id$='create-dashboard-action']"); - waitForElementDisplayed(By.cssSelector("div[id$=':create-new-dashboard-section']"), true); - clickByCssSelector("a[id$=':create-from-scratch']"); - waitForElementDisplayed(By.cssSelector("div[id$=':dashboard-creation-details-dialog']"), true); - findElementByCssSelector("[id$=':dashboard-title']").sendKeys("My dashboard"); - } - - public void openEditPublicDashboards() { - selectPublicDashboardType(); - clickByCssSelector("button[id$='dashboard-modification-component:dashboard-table:0:edit']"); - waitForElementDisplayed(By.cssSelector("[id$='dashboard-modification-container']"), true); - } - - public void reorderPublicDashboards() { - selectPublicDashboardType(); - clickByCssSelector("a[id$='reorder-dashboard-action'].js-public-dashboard"); - waitForElementDisplayed(By.cssSelector("[id$='reorder-dashboard-form:public-dashboard-table']"), true); - } - - public WebElement getDashboardTemplates() { - return findElementByCssSelector("[id$=':create-new-dashboard-form']"); - } - - public WebElement getDashboardCreationDialog() { - mouseOver(findElementByCssSelector("input[id$=':dashboard-detail-form:dashboard-title']")); - waitForElementDisplayed(By.cssSelector("input[id$=':dashboard-detail-form:dashboard-title']"), true); - return findElementByCssSelector("div[id$=':dashboard-creation-details-dialog']"); - } - - public WebElement getAddLanguageButton() { - return findElementByCssSelector("button[id$=':add-language-button']"); - } - - public void openMultiLanguageDialog() { - clickByCssSelector("button[id$=':add-language-button']"); - waitForElementDisplayed( - By.cssSelector("div[id$=':dashboard-creation-component:title-language-config:multiple-languages-dialog']"), - true); - } - - public void cancelMultiLanguageDialog() { - clickByCssSelector("a[id$=':multi-language-cancel-button']"); - } - - public void clickOkMultiLanguageDialog() { - waitForElementDisplayed(By.cssSelector("button[id$=':multi-language-ok-button']"), true); - clickByCssSelector("button[id$=':multi-language-ok-button']"); - } - - public WebElement getDashboardMultiLanguageDialog() { - waitForElementDisplayed(By.cssSelector( - "div[id$='dashboard-template-selection-component:dashboard-creation-component:title-language-config:multiple-languages-dialog']"), - true); - return findElementById( - "dashboard-template-selection-component:dashboard-creation-component:title-language-config:multiple-languages-dialog"); - } - - public void openImportPublicDashboards() { - selectPublicDashboardType(); - waitForElementDisplayed(By.cssSelector("div[id$=':create-new-dashboard-section']"), true); - openImportDashboardDialog(); - } - - public void openImportPrivateDashboards() { - createPrivateDashboard(); - openImportDashboardDialog(); - } - - public void openImportDashboardDialog() { - clickByCssSelector("a[id$=':import-dashboard']"); - waitForElementDisplayed(By.cssSelector("div[id$=':dashboard-import-dialog']"), true); - findElementByCssSelector("[id$=':dashboard-upload_input']").sendKeys(FileHelper.getAbsolutePathToTestFile("Dashboard_Dashboard_Export.json")); - waitForElementDisplayed(By.cssSelector("input[id$=':import-dashboard-form:0:import-dashboard-title']"), true); - } - - - public WebElement getImportDashboardDialog() { - mouseOver(findElementByCssSelector("input[id$=':import-dashboard-form:0:import-dashboard-title']")); - waitForElementDisplayed(By.cssSelector("input[id$=':import-dashboard-form:0:import-dashboard-title']"), true); - return findElementByCssSelector("div[id$=':dashboard-import-dialog']"); - } - - public void clickOnTextToTranslate(int index) { - clickByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", index)); - waitForElementDisplayed(By.cssSelector("div[id$=':overlay-panel-input']"), true); - } - - public void setTranslatedTitle() { - findElementByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", 1)) - .sendKeys(Keys.CONTROL, "a"); - findElementByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", 1)) - .sendKeys("Mon tableau de bord"); - - findElementByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", 2)) - .sendKeys(Keys.CONTROL, "a"); - findElementByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", 2)) - .sendKeys("Mein Armaturenbrett"); - findElementByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", 3)) - .sendKeys(Keys.CONTROL, "a"); - findElementByCssSelector(String.format("input[id$=':add-language-detail-form:table-titles:%s:title-input']", 3)) - .sendKeys("Mi cuadro de mandos"); - } - - public WebElement getShareDashboardDialog() { - clickByCssSelector("button[id$=':share-dashboard']"); - waitForElementDisplayed(By.cssSelector("div[id$=':share-dashboard-dialog']"), true); - return findElementByCssSelector("div[id$=':share-dashboard-dialog']"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardWidgetConfigurationDialogPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardWidgetConfigurationDialogPage.java deleted file mode 100644 index 9b00f9c14a3..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DashboardWidgetConfigurationDialogPage.java +++ /dev/null @@ -1,241 +0,0 @@ -package portal.guitest.page; - -import java.util.List; - -import org.apache.commons.collections4.CollectionUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class DashboardWidgetConfigurationDialogPage extends TemplatePage { - - private static final String MANAGE_COLUMN_LINK_ID = "widget-configuration-form:new-widget-configuration-component:%s-widget-preview:column-toggler"; - private static final String MANAGE_COLUMN_DIALOG_ID = "widget-configuration-form:new-widget-configuration-component:column-management-component:column-management-dialog"; - private static final String MANAGE_COLUMN_TABLE_CONTENT_ID = "widget-configuration-form:new-widget-configuration-component:column-management-component:column-management-form:column-management-datatable_data"; - private static final String MANAGE_COLUMN_SAVE_BUTTON_ID = "widget-configuration-form:new-widget-configuration-component:column-management-component:column-management-save-btn"; - private static final String MANAGE_COLUMN_CANCEL_LINK_ID = "widget-configuration-form:new-widget-configuration-component:column-management-component:column-management-cancel-link"; - - private static final String CONFIGURATION_DIALOG_ID = "new-widget-configuration-dialog"; - private static final String CONFIGURATION_FILTER_ID = "widget-configuration-form:new-widget-configuration-component:filter-container"; - private static final String PREVIEW_BUTTON_ID = "widget-configuration-form:new-widget-configuration-component:preview-button"; - - private static final String PROCESS_DISPLAY_MODE_ID = "widget-configuration-form:new-widget-configuration-component:process-display-mode"; - private static final String PROCESS_DISPLAY_MODE_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:process-display-mode_panel"; - private static final String COMBINED_MODE_PROCESS_SELECTION_ID = "widget-configuration-form:new-widget-configuration-component:selected-combined-process_input"; - private static final String COMBINED_MODE_PROCESS_SELECTION_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:selected-combined-process_panel"; - private static final String PROCESSES_LIST_ID = "widget-configuration-form:new-widget-configuration-component:processes-list"; - private static final String PROCESSES_LIST_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:processes-list_panel"; - private static final String FULL_MODE_PROCESS_SELECTION_ID = "widget-configuration-form:new-widget-configuration-component:selected-full-process_input"; - private static final String FULL_MODE_PROCESS_SELECTION_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:selected-full-process_panel"; - private static final String IMAGE_MODE_PROCESS_SELECTION_ID = "widget-configuration-form:new-widget-configuration-component:selected-image-process_input"; - private static final String IMAGE_MODE_PROCESS_SELECTION_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:selected-image-process_panel"; - private static final String PROCESS_VIEWER_PROCESS_SELECTION_ID = "widget-configuration-form:new-widget-configuration-component:selected-process_input"; - private static final String PROCESS_VIEWER_PROCESS_SELECTION_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:selected-process_panel"; - private static final String STATISTIC_CHART_FILTER_LIST_SELECTION_ID = "widget-configuration-form:new-widget-configuration-component:statistic-list_input"; - private static final String STATISTIC_CHART_FILTER_LIST_SELECTION_PANEL_ID = "widget-configuration-form:new-widget-configuration-component:statistic-list_panel"; - - @Override - protected String getLoadedLocator() { - return "id('new-widget-configuration-dialog')"; - } - - public WebElement openManageColumnDialog(boolean isTask) { - String manageColumnLinkId = isTask ? String.format(MANAGE_COLUMN_LINK_ID, "task") : String.format(MANAGE_COLUMN_LINK_ID, "case"); - waitForElementDisplayed(By.id(manageColumnLinkId), true); - findElementById(manageColumnLinkId).click(); - waitForElementDisplayed(By.id(MANAGE_COLUMN_DIALOG_ID), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, - "widget-configuration-form\\\\:new-widget-configuration-component\\\\:column-management-component\\\\:column-management-form\\\\:field-type-selection", - ID_PROPERTY); - return findElementById(MANAGE_COLUMN_DIALOG_ID); - } - - public void closeManageColumnDialog() { - findElementById(MANAGE_COLUMN_CANCEL_LINK_ID).click(); - waitForElementDisplayed(By.id(MANAGE_COLUMN_DIALOG_ID), false); - } - - public void closeConfigurationDialog() { - findElementById("task-configuration-cancel-link").click(); - waitForElementDisplayed(By.id(CONFIGURATION_DIALOG_ID), false); - } - - public void saveConfiguration() { - findElementById("widget-configuration-save-button").click(); - waitForElementDisplayed(By.id(CONFIGURATION_DIALOG_ID), false); - } - - public void uncheckTaskColumn(List columns, boolean isTask) { - if (CollectionUtils.isEmpty(columns)) { - return; - } - - WebElement configurationDialog = openManageColumnDialog(isTask); - List columnRows = - configurationDialog.findElement(By.id(MANAGE_COLUMN_TABLE_CONTENT_ID)).findElements(By.cssSelector("tr")); - - for (int i = 0; i < columnRows.size(); i++) { - int indexOfRow = i + 1; - WebElement columnRow = - findElementByCssSelector( - "#" + MANAGE_COLUMN_TABLE_CONTENT_ID.replace(":", "\\:") + " tr:nth-child(" + indexOfRow + ")"); - - WebElement nameCell = columnRow.findElements(By.cssSelector("td")).get(1); - if (columns.contains(nameCell.getText())) { - WebElement checkbox = - columnRow.findElements(By.cssSelector("td")).get(0).findElement(By.className("ui-chkbox")); - String checkboxId = checkbox.getAttribute("id"); - checkbox.click(); - waitForElementPresent(By.cssSelector("#" + checkboxId.replace(":", "\\:") + " .ui-icon-blank"), true, - DEFAULT_TIMEOUT); - } - } - - findElementById(MANAGE_COLUMN_SAVE_BUTTON_ID).click(); - waitForElementDisplayed(By.id(MANAGE_COLUMN_DIALOG_ID), false); - } - - public WebElement getConfigurationDialog() { - waitForElementDisplayed(By.id(CONFIGURATION_DIALOG_ID), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ajax-indicator\\\\:ajax-indicator-ajax-indicator_start", ID_PROPERTY); - return findElementById(CONFIGURATION_DIALOG_ID); - } - - public WebElement getConfigurationFilter() { - waitForElementDisplayed(By.id(CONFIGURATION_FILTER_ID), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "widget-configuration-form\\\\:new-widget-configuration-component\\\\:widget-title", ID_PROPERTY); - return findElementById(CONFIGURATION_FILTER_ID); - } - - public void clickProcessDisplayMode() { - waitForElementDisplayed(By.id(PROCESS_DISPLAY_MODE_ID), true); - findElementById(PROCESS_DISPLAY_MODE_ID).click(); - waitForElementDisplayed(By.id(PROCESS_DISPLAY_MODE_PANEL_ID), true); - } - - public void selectProcessMode(String name) { - clickProcessDisplayMode(); - WebElement processDisplayModePanel = findElementById(PROCESS_DISPLAY_MODE_PANEL_ID); - List modes = processDisplayModePanel.findElements(By.className("ui-selectonemenu-item")); - for (WebElement mode : modes) { - if (mode.getText().contentEquals(name)) { - mode.click(); - waitUntilAnimationFinished(9L, "ajax-indicator:ajax-indicator-ajax-indicator_start", "id"); - break; - } - } - } - - public void selectProcessForCombinedModeProcessWidget(String processName) { - waitForElementDisplayed(By.id(COMBINED_MODE_PROCESS_SELECTION_ID), true); - findElementById(COMBINED_MODE_PROCESS_SELECTION_ID).clear(); - findElementById(COMBINED_MODE_PROCESS_SELECTION_ID).sendKeys(processName); - waitForElementDisplayed(By.id(COMBINED_MODE_PROCESS_SELECTION_PANEL_ID), true); - findElementById(COMBINED_MODE_PROCESS_SELECTION_PANEL_ID).findElements(By.className("ui-autocomplete-item")).get(0).click(); - } - - public void selectProcessForFullModeProcessWidget(String processName) { - waitForElementDisplayed(By.id(FULL_MODE_PROCESS_SELECTION_ID), true); - findElementById(FULL_MODE_PROCESS_SELECTION_ID).clear(); - findElementById(FULL_MODE_PROCESS_SELECTION_ID).sendKeys(processName); - waitForElementDisplayed(By.id(FULL_MODE_PROCESS_SELECTION_PANEL_ID), true); - findElementById(FULL_MODE_PROCESS_SELECTION_PANEL_ID).findElements(By.className("ui-autocomplete-item")).get(0).click(); - } - - public void selectProcessForImageModeProcessWidget(String processName) { - waitForElementDisplayed(By.id(IMAGE_MODE_PROCESS_SELECTION_ID), true); - findElementById(IMAGE_MODE_PROCESS_SELECTION_ID).clear(); - findElementById(IMAGE_MODE_PROCESS_SELECTION_ID).sendKeys(processName); - waitForElementDisplayed(By.id(IMAGE_MODE_PROCESS_SELECTION_PANEL_ID), true); - findElementById(IMAGE_MODE_PROCESS_SELECTION_PANEL_ID).findElements(By.className("ui-autocomplete-item")).get(0).click(); - } - - public void selectProcessesForCompactProcessWidget(List processes) { - waitForElementDisplayed(By.id(PROCESSES_LIST_ID), true); - findElementById(PROCESSES_LIST_ID).click(); - if (processes == null) { - return; - } - - waitForElementDisplayed(By.id(PROCESSES_LIST_PANEL_ID), true); - List options = findElementById(PROCESSES_LIST_PANEL_ID).findElements(By.className("ui-selectcheckboxmenu-item")); - for(WebElement option : options) { - if (processes.contains(option.findElement(By.cssSelector("label")).getText())) { - option.findElement(By.className("ui-chkbox")).click(); - waitUntilAnimationFinished(9L, "ajax-indicator:ajax-indicator-ajax-indicator_start", "id"); - } - } - } - - public void clickPreviewButton() { - waitForElementDisplayed(By.id(PREVIEW_BUTTON_ID), true); - findElementById(PREVIEW_BUTTON_ID).click(); - } - - public void waitForCombinedProcessLoadedAfterClickPreview() { - waitForElementDisplayed(By.cssSelector("[id$=':process-task-widget-component:dashboard-process-tasks_data']"), true); - } - - public void waitForCompactProcessLoadedAfterClickPreview() { - waitForElementDisplayed(By.cssSelector("div[id$=':process-list'] .process-start-list-item"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ajax-indicator\\\\:ajax-indicator-ajax-indicator_start", ID_PROPERTY); - waitUntilAnimationFinished(9L, "process-start-list-item", "class"); - } - - public void waitForFullProcessLoadedAfterClickPreview() { - waitForElementDisplayed(By.cssSelector("form[id$=':process-grid-item:process-item']"), true); - } - - public void waitForImageProcessLoadedAfterClickPreview() { - waitForElementDisplayed(By.id("process-actions"), true); - } - - public void selectProcessForProcessViewerWidget(String processName) { - waitForElementDisplayed(By.id(PROCESS_VIEWER_PROCESS_SELECTION_ID), true); - findElementById(PROCESS_VIEWER_PROCESS_SELECTION_ID).clear(); - findElementById(PROCESS_VIEWER_PROCESS_SELECTION_ID).sendKeys(processName); - waitForElementDisplayed(By.id(PROCESS_VIEWER_PROCESS_SELECTION_PANEL_ID), true); - findElementById(PROCESS_VIEWER_PROCESS_SELECTION_PANEL_ID).findElements(By.className("ui-autocomplete-item")).get(0).click(); - } - - public void selectChartNameForStatisticChartWidget(String chartName) { - waitForElementDisplayed(By.id(STATISTIC_CHART_FILTER_LIST_SELECTION_ID), true); - findElementById(STATISTIC_CHART_FILTER_LIST_SELECTION_ID).clear(); - findElementById(STATISTIC_CHART_FILTER_LIST_SELECTION_ID).sendKeys(chartName); - waitForElementDisplayed(By.id(STATISTIC_CHART_FILTER_LIST_SELECTION_PANEL_ID), true); - findElementById(STATISTIC_CHART_FILTER_LIST_SELECTION_PANEL_ID).findElements(By.className("ui-autocomplete-item")) - .get(0) - .click(); - } - - public void waitForStatisticChartLoadedAfterClickPreview() { - waitForElementDisplayed(By.cssSelector("[id$=':task_by_priority_chart-']"), true); - } - - public void waitUntilAnimationFinished() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ajax-indicator\\\\:ajax-indicator-ajax-indicator_start", ID_PROPERTY); - } - - public void openMultiLanguageDialog() { - clickByCssSelector("button[id$=':add-language-button']"); - waitForElementDisplayed( - By.cssSelector( - "div[id$='widget-configuration-form:new-widget-configuration-component:title-language-config:multiple-languages-dialog']"), - true); - } - - public void clickOkMultiLanguageDialog() { - clickByCssSelector( - "button[id$='widget-configuration-form:new-widget-configuration-component:title-language-config:add-language-detail-form:multi-language-ok-button']"); - waitUntilAnimationFinished(); - } - - public WebElement getMultiLanguageDialogForTaskWidget() { - return findElementById( - "widget-configuration-form:new-widget-configuration-component:title-language-config:multiple-languages-dialog"); - } - - public WebElement getAddingFieldColumnType() { - return findElementById( - "widget-configuration-form:new-widget-configuration-component:column-management-component:column-management-form:field-type-selection_label"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DefaultExpresTaskPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DefaultExpresTaskPage.java deleted file mode 100644 index 6b6111296cf..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DefaultExpresTaskPage.java +++ /dev/null @@ -1,23 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class DefaultExpresTaskPage extends TaskTemplatePage{ - - @Override - protected String getLoadedLocator() { - return "id('form:cancel-btn')"; - } - - public void enterTextToDefaultTask(String text) { - var textArea = findElementByCssSelector("#form\\:user-task-dyna-form textarea[id$='input-text-area']"); - type(textArea, text); - var textAreaId = textArea.getAttribute(ID_PROPERTY); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, textAreaId.replace(":", "\\\\:"), ID_PROPERTY); - } - - public void finishDefaultTask() { - click(By.id("form:ok-btn")); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DocumentTableComponentPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DocumentTableComponentPage.java deleted file mode 100644 index a2f478ffa08..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/DocumentTableComponentPage.java +++ /dev/null @@ -1,38 +0,0 @@ -package portal.guitest.page; - -import java.util.List; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class DocumentTableComponentPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('form:document-table-component')"; - } - - public void uploadSampleDocument(String pathToFile) { - click(By.id("form:document-table-component:document-upload")); - waitForElementExisted("input[id$='form:document-table-component:document-upload_input']", true, DEFAULT_TIMEOUT); - findElementByCssSelector("input[id$='form:document-table-component:document-upload_input']").sendKeys(pathToFile); - waitForElementDisplayed(getDocuments().get(0), true); - waitForElementDisplayed(By.cssSelector("span[class$='ui-messages-info-summary']"), true); - } - - private List getDocuments() { - return findElementById("form:document-table-component:document-table").findElement(By.cssSelector("table tbody")).findElements(By.cssSelector("tr")); - } - - public void waitForDocumentTableComponentPageLoaded() { - waitForElementDisplayed(By.id("form:document-table-component"), true); - } - - public WebElement getDocumentTableComponent() { - return findElementById("form:document-table-component"); - } - - public int countDocuments() { - return getDocuments().size(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExampleOverviewPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExampleOverviewPage.java deleted file mode 100644 index 9277cab5064..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExampleOverviewPage.java +++ /dev/null @@ -1,33 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class ExampleOverviewPage extends TemplatePage { - @Override - protected String getLoadedLocator() { - return "id('example-header')"; - } - - @SuppressWarnings("deprecation") - public LeaveRequestOverviewPage openLeaveRequestOverview() { - clickByCssSelector("[id$='0:more-info']"); - waitAjaxIndicatorDisappear(); - return new LeaveRequestOverviewPage(); - } - - @SuppressWarnings("deprecation") - public LendingOverviewPage openLendingOverview() { - clickByCssSelector("[id$='1:more-info']"); - waitAjaxIndicatorDisappear(); - return new LendingOverviewPage(); - } - - public void startUserExampleProcess(int index) { - String userProcessId = String.format("[id$=':%d:start-button']", index); - click(findElementByCssSelector(userProcessId)); - } - - public void waitUntilExampleOverviewDisplayed() { - waitForElementDisplayed(By.id("example-header"), true); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressApprovalPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressApprovalPage.java deleted file mode 100644 index 0203dfc5d87..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressApprovalPage.java +++ /dev/null @@ -1,28 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class ExpressApprovalPage extends TaskTemplatePage { - - public void approve() { - clickOnApprove(); - new TaskWidgetPage(); - } - - public void clickOnApprove() { - click(By.cssSelector("button[id$='approve-btn']")); - } - - public void reject() { - click(By.id("form:refuse-btn")); - } - - public void waitForCommentContainerDisplay() { - waitForElementDisplayed(By.className("approval-comment-container"), true); - } - - public void comment(String comment) { - findElementByCssSelector("textarea[id$='comment']").sendKeys(comment); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressBusinessViewPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressBusinessViewPage.java deleted file mode 100644 index 41891e13bec..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressBusinessViewPage.java +++ /dev/null @@ -1,65 +0,0 @@ -package portal.guitest.page; - -import java.util.stream.Collectors; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class ExpressBusinessViewPage extends TaskTemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('express-view-form')"; - } - - public WebElement getEmptyFinishedTask() { - return findElementByCssSelector("[id$='express-view-form:empty-finished-tasks-container']"); - } - - public String getEmptyFinishedTaskMessage() { - WebElement message = getEmptyFinishedTask().findElement(By.className("no-item-header")); - return message.getText(); - } - - public NewDashboardPage clickOnCloseButton() { - click(findElementByCssSelector("[id$='express-view-form:cancel-btn']")); - return new NewDashboardPage(); - } - - public WebElement getLegendFisnishedTaskFieldset(int index) { - return findElementByCssSelector(String.format("span[id$=':finished-tasks-component:approval-result:%d:finished-task-fieldset-legend']", index)); - } - - public String getTextOfLegendFinishedTask(int index) { - return getLegendFisnishedTaskFieldset(index).getText(); - } - - public String getTextOfLegendApprovalResult(int index) { - WebElement approvalResult = findElementByCssSelector(String.format("span[id$=':approval-result-container:0:approval-result-fieldset-legend']", index)); - return approvalResult.getText(); - } - - public void clickOnLegendOfFieldset(int index) { - click(getLegendFisnishedTaskFieldset(index)); - } - - public String getApprovalResultsText() { - WebElement approvalTable = findElementByClassName("approval-result-content"); - return approvalTable.findElements(By.cssSelector("tbody[id$=':approval-result-table_data'] td")).stream().map(WebElement::getText) - .collect(Collectors.joining(",")); - } - - public Integer getIndexOfCurrentProcessChain() { - waitForElementDisplayed(By.cssSelector("div.process-chain-container.vertical-chain-shape-line"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "line-horizontal-step-container", CLASS_PROPERTY); - WebElement processChainContainer = findElementByCssSelector("[id$='process-chain-component:process-chain-component-id']"); - for (var step : processChainContainer.findElements(By.cssSelector("div[id^='process-chain-component:step-info-']"))) { - if (step.getAttribute(CLASS_PROPERTY).contains("current")) { - String stepId = step.getAttribute("id"); - return Integer.valueOf(stepId.replace("process-chain-component:step-info-", "").trim()).intValue(); - } - } - return 0; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressEndPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressEndPage.java deleted file mode 100644 index eef4de4cbd4..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressEndPage.java +++ /dev/null @@ -1,14 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class ExpressEndPage extends TemplatePage { - @Override - protected String getLoadedLocator() { - return "id('form:close-button')"; - } - - public void finish() { - click(By.id("form:close-button")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressFormDefinitionPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressFormDefinitionPage.java deleted file mode 100644 index f3cf0941d3c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressFormDefinitionPage.java +++ /dev/null @@ -1,262 +0,0 @@ -package portal.guitest.page; - -import java.util.Random; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.Action; -import org.openqa.selenium.interactions.Actions; - -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; -import vn.wawa.guitest.base.client.Browser; - -public class ExpressFormDefinitionPage extends TemplatePage { - - private static final int TIME_OUT = 60; - private static final String LEFT_POSITION = "leftpanel"; - private static final String RIGHT_POSITION = "rightpanel"; - private static final String HEADER_POSITION = "header"; - private static final String FOOTER_POSITION = "footer"; - private static final String[] POSITIONS = {LEFT_POSITION, HEADER_POSITION, FOOTER_POSITION}; - - @Override - protected String getLoadedLocator() { - return "id('form:create-tabs')"; - } - - @SuppressWarnings("deprecation") - public void createTextInputField(String label, int inputFieldTypeIndex, boolean isRequired) { - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][1]")); - waitForElementDisplayed(By.id("form:create-tabs:create-input-field-tab"), true, TIME_OUT); - type(By.id("form:create-tabs:input-field-label"), label); - chooseInputFieldType(inputFieldTypeIndex); - if (isRequired) { - click(By.cssSelector("div[id='form:create-tabs:input-field-required']")); - } - click(By.id("form:create-tabs:add-input-text-btn")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void createTextAreaField(String label, boolean isRequired) { - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][2]")); - ensureNoBackgroundRequest(); - waitForElementDisplayed(By.id("form:create-tabs:create-input-area-tab"), true, TIME_OUT); - type(By.id("form:create-tabs:input-area-label"), label); - if (isRequired) { - click(By.cssSelector("div[id='form:create-tabs:input-area-required']")); - } - click(By.id("form:create-tabs:add-text-area-btn")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void createCheckboxField(String label, int numberOfSelection) { - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][3]")); - ensureNoBackgroundRequest(); - waitForElementDisplayed(By.id("form:create-tabs:many-checkbox-options"), true, TIME_OUT); - type(By.id("form:create-tabs:many-checkbox-label"), label); - addCheckboxOptions(numberOfSelection); - click(By.id("form:create-tabs:add-checkbox-btn")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - public void switchToCheckBoxTab() { - waitForElementDisplayed(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][3]"), true); - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][3]")); - WaitHelper.assertTrueWithWait(() -> { - var checkboxTab = findElementByXpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][3]"); - return checkboxTab.getAttribute(CLASS_PROPERTY).contains("ui-state-active"); - }); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-tabs-header.ui-tabs-selected.ui-state-active", CLASS_PROPERTY); - waitForElementDisplayed(By.id("form:create-tabs:many-checkbox-options"), true, TIME_OUT); - } - - @SuppressWarnings("deprecation") - public void createCheckboxFieldWithDataProvider(String label) { - fillDataForCheckboxProvider(label); - click(By.id("form:create-tabs:add-checkbox-btn")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void fillDataForCheckboxProvider(String label) { - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][3]")); - ensureNoBackgroundRequest(); - waitForElementDisplayed(By.id("form:create-tabs:create-many-checkbox-tab"), true, TIME_OUT); - click(By.id("form:create-tabs:DataProvider_label")); - click(By.xpath("//*[@data-label='TestDataProviderForPortalExpress']")); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.id("form:create-tabs:many-checkbox-label"), true, TIME_OUT); - type(By.id("form:create-tabs:many-checkbox-label"), label); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void createRadioButtonField(String label, int numberOfOption) { - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][4]")); - ensureNoBackgroundRequest(); - waitForElementDisplayed(By.id("form:create-tabs:one-radio-label"), true, TIME_OUT); - type(By.id("form:create-tabs:one-radio-label"), label); - addRadioOptions(numberOfOption); - click(By.id("form:create-tabs:add-radio-btn")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void createUploadComponent(String label) { - click(By.xpath("//*[@id='form:create-tabs']/ul/li[@role='tab'][5]")); - ensureNoBackgroundRequest(); - waitForElementDisplayed(By.id("form:create-tabs:create-file-upload-tab"), true, TIME_OUT); - type(By.id("form:create-tabs:file-upload-label"), label); - click(By.id("form:create-tabs:add-upload-file-btn")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - private void addRadioOptions(int numberOfOptions) { - for (int i = 1; i <= numberOfOptions; i++) { - click(By.id("form:create-tabs:one-radio-options:add-radio-option-btn")); - waitAjaxIndicatorDisappear(); - type(By.xpath(String.format("//*[@id='form:create-tabs:one-radio-options_data']/tr[%d]/td/input", i)), "Radio " + i); - } - } - - @SuppressWarnings("deprecation") - private void addCheckboxOptions(int numberOfSelection) { - for (int i = 1; i <= numberOfSelection; i++) { - click(By.id("form:create-tabs:many-checkbox-options:add-checkbox-option-btn")); - waitAjaxIndicatorDisappear(); - type(By.xpath(String.format("//*[@id='form:create-tabs:many-checkbox-options_data']/tr[%d]/td/input", i)), - "Option " + i); - } - } - - private void chooseInputFieldType(int inputTypeIndex) { - click(By.id("form:create-tabs:input-field-type_label")); - waitForElementDisplayed(By.id("form:create-tabs:input-field-type_panel"), true); - click(By.id(String.format("form:create-tabs:input-field-type_%d", inputTypeIndex))); - } - - public void moveAllElementToDragAndDrogPanel() { - int size = driver.findElements(By.xpath("//div[@id='form:available-form-elements_content']/ul/li")).size(); - int startIndex = size - 1; - for (int i = startIndex; i >= 0; i--) { - waitForElementDisplayed(By.id("form:available-form-elements:" + i + ":pnl"), true, TIME_OUT); - if (i == startIndex) { - moveFormElementToPanel(i, RIGHT_POSITION); - } else { - moveFormElementToPanel(i, getRandomPosition()); - } - waitForElementExisted("[id$='form:available-form-elements:" + i + ":pnl']", false, DEFAULT_TIMEOUT); - } - } - - private void moveFormElementToPanel(int index, String position) { - //TODO Need to be fixed - Workaround for scroll-bar issue - JavascriptExecutor jse = (JavascriptExecutor) driver; - jse.executeScript("window.scrollTo(0, document.body.scrollHeight);"); - Sleeper.sleep(200); // Wait for JS executed successfully - var formElementSelector = String.format("[id$='form:available-form-elements:%d:pnl_content']", index); - // If elements is FileUpload, move to footer - if (formElementIsFileUpload(findElementByCssSelector(formElementSelector))) { - position = FOOTER_POSITION; - } - var panelId = String.format("form:selected-form-elements-%s-panel", position); - waitForElementDisplayed(By.id(panelId), true); - WebElement panel = findElementById(panelId); - Actions builder = new Actions(driver); - Action moveProcessSequence = builder.dragAndDrop(findElementByCssSelector(formElementSelector), panel).build(); - moveProcessSequence.perform(); - WaitHelper.assertTrueWithWait(() -> { - var dropPanel = findElementById(panelId); - return !dropPanel.getAttribute(CLASS_PROPERTY).contains("ui-droppable-hover"); - }); - } - - private String getRandomPosition() { - int idx = new Random().nextInt(POSITIONS.length); - return (POSITIONS[idx]); - } - - private boolean formElementIsFileUpload(WebElement formElement) { - WebElement icon = formElement.findElement(By.tagName("img")); - return icon.getAttribute("src").contains("FileUpload"); - } - - public int countNumberOfElementsInPreviewDialog() { - click(By.id("form:show-preview-button")); - waitForElementDisplayed(By.id("form:preview-dialog"), true); - WebElement previewDialog = findElementById("form:preview-dialog"); - int numberOfInput = previewDialog.findElements(By.xpath("//table[@id='form:dyna-form']//input")).size(); - int numberOfTextArea = previewDialog.findElements(By.xpath("//table[@id='form:dyna-form']//textarea")).size(); - int numberOfUploadFile = previewDialog.findElements(By.xpath("//div[contains(@id,'fileUploadComponent:document-table')]")).size(); - return numberOfInput + numberOfTextArea + numberOfUploadFile; - } - - public int countNumberOfSteps() { - return driver.findElements(By.xpath("//div[@id='defined-task-container']//button")).size(); - } - - public void finishWorkflow() { - click(By.id("finish-button")); - new NewDashboardPage().isDisplayed(); - } - - public void executeWorkflow() { - click(By.id("execute-button")); - waitForElementDisplayed(By.id("form:dynaform-fieldset"), true); - } - - public void executeWorkflowAndWaitForUserTaskWithEmailDisplay() { - click(By.id("execute-button")); - waitForElementDisplayed(By.id("task-form:task-view:dyna-form-fieldset"), true); - } - - @SuppressWarnings("deprecation") - public void nextStep() { - click(By.id("next-button")); - ensureNoBackgroundRequest(); - } - - public void inputMailRecipient(String content) { - findElementById("form:information-email:email-recipients").sendKeys(content); - } - - public void inputMailSubject(String content) { - findElementById("form:information-email:email-subject").sendKeys(content); - } - - public void inputMailContent(String content) { - WebDriver driver = Browser.getBrowser().getDriver(); - JavascriptExecutor jse = (JavascriptExecutor) driver; - jse.executeScript( - "document.querySelector(\"input[name='form:information-email:email-content_input'\").value='" + content + "';"); - } - - public NewDashboardPage leave() { - click(By.id("user-menu-required-login:warning-before-leaving-task-component:leave-button")); - return new NewDashboardPage(); - } - - public NewDashboardPage cancel() { - click(By.id("cancel-button")); - waitForElementDisplayed(By.id("yes-button"), true); - click(By.id("yes-button")); - return new NewDashboardPage(); - } - - public NewDashboardPage save() { - click(By.id("save-button")); - return new NewDashboardPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressManagementPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressManagementPage.java deleted file mode 100644 index 1d66fdab392..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressManagementPage.java +++ /dev/null @@ -1,104 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class ExpressManagementPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('admin-setting-component:adminTabView:express-management-component:express-management-form')"; - } - - public void openImportDialog() { - click(findElementByCssSelector("button[id$=':express-management-form:import-express-btn']")); - waitForElementDisplayed(findElementByCssSelector("[id$=':import-express-form:express-process-upload_label']"), true); - } - - public WebElement getImportExpressDialog() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-fileupload.express-process-upload", CLASS_PROPERTY); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ajax-indicator\\\\:ajax-indicator-ajax-indicator_start", ID_PROPERTY); - return findElementByCssSelector("[id$=':express-management-component:import-express-dialog']"); - } - - public boolean isImportDialogDisplayed() { - WebElement webElement = findElementByCssSelector("div[id$=':import-express-dialog']"); - return webElement.isDisplayed(); - } - - public void selectJSONFile(String pathToFile) { - findElementByCssSelector("*[id$=':express-process-upload_input']").sendKeys(pathToFile); - // currently haven't found solution to check when the file upload finish, we have to wait - Sleeper.sleep(2000); - } - - public void clickOnCloseButton() { - WebElement closeButton = findElementByCssSelector("*[id$=':close-import-express']"); - Awaitility.await().atMost(new Duration(10, TimeUnit.SECONDS)).until(() -> closeButton.isEnabled()); - click(closeButton); - waitForElementDisplayed(By.cssSelector("*[id$=':close-import-express']"), false); - } - - public void clickOnDeployExpress() { - WebElement deployButton = waitForDeployButtonEnabled(); - click(deployButton); - waitForElementDisplayed(By.id("admin-setting-component:adminTabView:express-management-component:import-express-form:impress-export-output"), true); - waitForElementEnabled(By.id("admin-setting-component:adminTabView:express-management-component:close-import-express"), true, DEFAULT_TIMEOUT); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "adminui\\\\:adminTabView\\\\:express-management-component\\\\:close-import-express", ID_PROPERTY); - } - - public WebElement waitForDeployButtonEnabled() { - WebElement deployButton = findElementByCssSelector(".ui-fileupload-upload"); - waitForElementDisplayed(deployButton, true); - return deployButton; - } - - public String getUploadMessage() { - waitForElementDisplayed(By.cssSelector("div[class$='ui-fileupload-messages'] span[class$='ui-messages-error-summary']"), true); - return driver.findElement(By.cssSelector("div[class$='ui-fileupload-messages'] span[class$='ui-messages-error-summary']")).getText(); - } - - public void clickOnSelectAllExpresses() { - var importHeader = findElementByCssSelector("[id$=':express-management-form:express-workflow-summary-table_head']"); - WaitHelper.assertTrueWithWait(() -> { - var checkboxAll = importHeader.findElement(By.cssSelector(".ui-chkbox-box.ui-corner-all")); - return !checkboxAll.getAttribute(CLASS_PROPERTY).contains("ui-state-disabled"); - }); - selectExpressCheckboxByIndex(0); - } - - public void selectExpressCheckboxByIndex(int index) { - WebElement expressTable = findElementByCssSelector("[id$=':express-management-component:express-management-form:express-workflow-summary-table']"); - List checkboxSelections = findChildElementsByClassName(expressTable, "express-selection-column"); - if (checkboxSelections.size() > index) { - var checkbox = findChildElementByClassName(checkboxSelections.get(index), "ui-chkbox-box"); - click(checkbox); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, checkbox.getAttribute(CLASS_PROPERTY).replace(" ", "."), CLASS_PROPERTY); - } - } - - public void clickOnExportButton() { - waitForElementEnabled(By.cssSelector("[id$=':express-management-component:express-management-form:export-express-btn']"), true, DEFAULT_TIMEOUT); - click(findElementByCssSelector("[id$=':express-management-component:express-management-form:export-express-btn']")); - waitForElementDisplayed(By.id("admin-setting-component:adminTabView:express-management-component:export-express-dialog"), true); - } - - public WebElement getExportExpressDialog() { - return findElementByCssSelector("[id$=':express-management-component:export-express-dialog']"); - } - - public void deployExpressFile() { - clickOnDeployExpress(); - clickOnCloseButton(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressProcessPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressProcessPage.java deleted file mode 100644 index 2015c916934..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressProcessPage.java +++ /dev/null @@ -1,176 +0,0 @@ -package portal.guitest.page; - -import java.util.List; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class ExpressProcessPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('form:process-setting-fieldset')"; - } - - public void fillProcessProperties(boolean isAdhocWF, boolean isCreateOwn, String processName, - String processDescription) { - if (isAdhocWF) { - click(By.cssSelector("div[id='form:process-type']")); - WaitHelper.assertTrueWithWait(() -> "One time".equals(findElementByCssSelector("label.switch-active").getText())); - } - - if (!isCreateOwn) { - click(By.cssSelector("div[id='form:user-interface-type']")); - agreeToDeleteAllDefineTasks(); - } - type(By.id("form:process-name"), processName); - type(By.id("form:process-description"), processDescription); - } - - private void selectCheckbox(String forAttribute) { - WebElement checkboxLabel = findElementByXpath(String.format("//label[@for='%s']", forAttribute)); - click(checkboxLabel); - } - - public void createTask(int taskIndex, int typeIndex, String taskName, String taskDescription, - List responsibles) { - final String TASK_NAME_FORMAT = "input[id$='%d:task-name']"; - final int INFORMATION_EMAIL_INDEX = 2; - - chooseTaskType(taskIndex, typeIndex); - Sleeper.sleep(1000); - if (typeIndex != INFORMATION_EMAIL_INDEX) { - WaitHelper.typeWithRetry(this, String.format(TASK_NAME_FORMAT, taskIndex), taskName); - WaitHelper.typeWithRetry(this, String.format("input[id$='%d:task-description']", taskIndex), taskDescription); - click(By.id(String.format("form:defined-tasks-list:%d:task-responsible-link", taskIndex))); - waitForElementDisplayed(By.id("choose-responsible-dialog"), true); - for (ExpressResponsible responsible : responsibles) { - chooseResponsible(responsible.getResponsibleName(), responsible.isGroup()); - } - click(By.id("assignee-selection-form:save-assignee-button")); - } - } - - public void createDefaultTask(int taskIndex, String taskName, List responsibles) { - if (taskName != null) { - type(By.id(String.format("form:defined-tasks-list:%d:default-task-name", taskIndex)), taskName); - } - click(By.id(String.format("form:defined-tasks-list:%d:default-task-responsible-link", taskIndex))); - addResponsible(responsibles); - } - - private void addResponsible(List responsibles) { - waitForElementDisplayed(By.id("choose-responsible-dialog"), true); - for (ExpressResponsible responsible : responsibles) { - chooseResponsible(responsible.getResponsibleName(), responsible.isGroup()); - } - click(By.id("assignee-selection-form:save-assignee-button")); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "choose-responsible-dialog", ID_PROPERTY); - } - - public ExpressFormDefinitionPage goToFormDefinition() { - click(By.id("form:save")); - return new ExpressFormDefinitionPage(); - } - - @SuppressWarnings("deprecation") - public void addNewTask(int currentTaskIndex) { - click(By.id(String.format("form:defined-tasks-list:%d:add-step-button", currentTaskIndex))); - ensureNoBackgroundRequest(); - } - - public void executeDirectly() { - click(By.id("form:save")); - } - - public void fillProcessOwners(List responsibles) { - click(By.id("form:process-owner-link")); - addResponsible(responsibles); - } - - private void chooseResponsible(String responsible, boolean isGroup) { - if (isGroup) { - selectCheckbox("assignee-selection-form:assignee-type:1"); - WaitHelper.assertTrueWithWait(() -> { - return findElementByCssSelector("[id$=':role-selection-autocomplete-panel']").isDisplayed(); - }); - waitForElementDisplayed(By.id("assignee-selection-form:role-selection-component:role-selection_input"), true); - type(By.id("assignee-selection-form:role-selection-component:role-selection_input"), responsible); - waitForElementDisplayed(By.id("assignee-selection-form:role-selection-component:role-selection_panel"), true); - click( - By.cssSelector("span[id='assignee-selection-form:role-selection-component:role-selection_panel'] .gravatar")); - } else { - type(By.id("assignee-selection-form:user-selection-component:user-selection_input"), responsible); - waitForElementDisplayed(By.id("assignee-selection-form:user-selection-component:user-selection_panel"), true); - click(By.xpath("//*[@id='assignee-selection-form:user-selection-component:user-selection_panel']/table/tbody/tr")); - } - WaitHelper.assertTrueWithWait(() -> isElementEnabled(By.id("assignee-selection-form:add-assignee-button"))); - click(By.id("assignee-selection-form:add-assignee-button")); - waitForElementDisplayed(By.className("assignee-name-col"), true); - var responsiblesSelection = findElementByCssSelector("[id$='assignee-selection-form:select-assignee']"); - var inputText = responsiblesSelection.findElement(By.cssSelector(".ui-autocomplete-input.ui-autocomplete-dd-input.ui-inputfield")); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, inputText.getAttribute(CLASS_PROPERTY).replace(" ", "."), CLASS_PROPERTY); - } - - private void chooseTaskType(int taskIndex, int typeIndex) { - if (typeIndex == 0) { - // If the selected task type is already task type? ignore click on the drop-down - return; - } - - final String TASK_TYPE_FORMAT = "li[id$=':%d:task-type_%d']"; - final String TASK_TYPE_LABEL_FORMAT = "label[id$=':%d:task-type_label']"; - - clickByCssSelector(String.format(TASK_TYPE_LABEL_FORMAT, taskIndex)); - waitForElementDisplayed(By.cssSelector(String.format("[id$=':%d:task-type_panel']", taskIndex)), true); - String taskType = findElementByCssSelector(String.format(TASK_TYPE_FORMAT, taskIndex, typeIndex)).getText(); - clickByCssSelector(String.format(TASK_TYPE_FORMAT, taskIndex, typeIndex)); - WaitHelper.assertTrueWithWait(() -> taskType.equals(findElementByCssSelector(String.format(TASK_TYPE_LABEL_FORMAT, taskIndex, taskIndex)).getText())); - } - - @SuppressWarnings("deprecation") - private void agreeToDeleteAllDefineTasks() { - waitForElementDisplayed(By.id("delete-all-defined-tasks-warning"), true); - click(By.id("delete-all-defined-tasks-warning-ok")); - waitAjaxIndicatorDisappear(); - Sleeper.sleep(2000); - } - - public String getProcessName() { - return findElementById("form:process-name").getAttribute("value"); - } - - public String getProcessOwnerNames() { - return findElementById("form:process-owner-link").getText(); - } - - public String getAbleToStartNames() { - return getResponsiblesOfTask(0); - } - - public String getResponsiblesOfTask(int taskIndex) { - return findElementById(String.format("form:defined-tasks-list:%d:task-responsible-link", taskIndex)).getText(); - } - - public WebElement getDefineTaskStep(int stepIndex) { - String defineTaskStepId = String.format(":defined-tasks-list:%s:process-flow-field", stepIndex); - return findElementByCssSelector("[id$='"+ defineTaskStepId + "']"); - } - - public void waitUntilExpressProcessDisplay() { - waitForElementDisplayed(By.id("form:process-setting-fieldset"), true); - } - - public void waitForChooseResponsibleDialogHidden() { - waitForElementDisplayed(findElementById("choose-responsible-dialog"), false); - } - - public NewDashboardPage cancelWorkflowDefinition() { - click(By.id("form:cancel-workflow-button")); - return new NewDashboardPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressReviewPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressReviewPage.java deleted file mode 100644 index 2a3264b77c8..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressReviewPage.java +++ /dev/null @@ -1,29 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.stream.Collectors; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.Sleeper; - -public class ExpressReviewPage extends TaskTemplatePage { - public void finish() { - clickByCssSelector("button[id$='acknowledged']"); - } - - public void clickOnOkButton() { - click(By.cssSelector("button[id$='close-button']")); - } - - public String getApprovalResult() { - List openFieldSetButtons = findListElementsByCssSelector("fieldset[id *= ':approval-result-fieldset'] .ui-icon-plusthick"); - for (WebElement elem : openFieldSetButtons) { - click(elem); - } - Sleeper.sleep(2000); - return findListElementsByCssSelector("div[id*='approval-result'] td").stream().map(WebElement::getText) - .collect(Collectors.joining(",")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressTaskPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressTaskPage.java deleted file mode 100644 index 0d7d7e6654f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ExpressTaskPage.java +++ /dev/null @@ -1,34 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class ExpressTaskPage extends TaskTemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('horizontal-case-info')"; - } - - public void finish() { - click(By.id("form:ok-btn")); - } - - public boolean isDocumentTableVisible() { - return isElementPresent(By.xpath("//div[contains(@id, 'fileUploadComponent:document-table')]")); - } - - public boolean isDocumentUploadButtonVisible() { - return isElementPresent(By.xpath("//div[contains(@id, 'fileUploadComponent:document-upload')]")); - } - - public void enterRequiredInputFieldByLabel(String label, String data) { - WebElement inputField = findElementByCssSelector(String.format("input[data-p-rmsg*='%s']", label)); - inputField.sendKeys(data); - } - - public void waitForExpressFieldSetDisplay() { - waitForElementDisplayed(By.className("express-fieldset"), true); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ForgotPasswordPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ForgotPasswordPage.java deleted file mode 100644 index 6326b98dcf4..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ForgotPasswordPage.java +++ /dev/null @@ -1,45 +0,0 @@ -package portal.guitest.page; - -import org.apache.commons.lang.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.TestAccount; -import vn.wawa.guitest.base.page.AbstractPage; - -public class ForgotPasswordPage extends AbstractPage { - private static final String RESULT_MESSAGE_SELECTOR = "span[class='ui-messages-info-summary'], span[class='ui-messages-error-summary']"; - - private static final long FORGOT_PASSWORD_TIMEOUT = 60; - - private WebElement emailTextField; - private WebElement sendButton; - private TestAccount testAccount; - - @Override - protected String getLoadedLocator() { - return "id('forgot-password:forgot-password-form:send-command')"; - } - - public ForgotPasswordPage() { - waitForPageLoaded(); - this.emailTextField = findElementByCssSelector("input[id='forgot-password:forgot-password-form:email']"); - this.sendButton = findElementByCssSelector("button[id='forgot-password:forgot-password-form:send-command']"); - } - - public ForgotPasswordPage(TestAccount testAccount) { - this(); - this.testAccount = testAccount; - } - - public void send() { - emailTextField.sendKeys(testAccount.getEmail()); - click(sendButton); - waitForElementDisplayed(By.cssSelector(RESULT_MESSAGE_SELECTOR), true, FORGOT_PASSWORD_TIMEOUT); - } - - public boolean isProcessed() { - WebElement summayMessageSpan = findElementByCssSelector(RESULT_MESSAGE_SELECTOR); - return summayMessageSpan != null && StringUtils.isNotBlank(summayMessageSpan.getText()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LeaveRequestOverviewPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LeaveRequestOverviewPage.java deleted file mode 100644 index 307e7d90744..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LeaveRequestOverviewPage.java +++ /dev/null @@ -1,29 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.userexamples.page.LeaveRequestPage; - -public class LeaveRequestOverviewPage extends TemplatePage { - @Override - protected String getLoadedLocator() { - return "id('leave-request-header')"; - } - - public String getHearText() { - WebElement element = findElementByCssSelector("[id$='leave-request-header']"); - return element.getText(); - } - - public String getStepName(int index) { - WebElement element = findElementByCssSelector(String.format("[id$=':%d:process-step']", index)); - return element.getText(); - } - - public LeaveRequestPage start() { - clickByCssSelector("button[id$='start']"); - waitForElementDisplayed(By.cssSelector("[id$='leave-request']"), true); - return new LeaveRequestPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingDetailPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingDetailPage.java deleted file mode 100644 index 1fd26678757..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingDetailPage.java +++ /dev/null @@ -1,56 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class LendingDetailPage extends TemplatePage { - int index; - @Override - protected String getLoadedLocator() { - return "id('lending-detail-header')"; - } - - public LendingDetailPage(int index) { - this.index = index; - } - - public String getHearText() { - WebElement element = findElementByCssSelector("[id$='lending-detail-header']"); - return element.getText(); - } - - public String getStageName() { - WebElement element = findElementByCssSelector(String.format("[id$='stage-%d-name']", index)); - return element.getText(); - } - - public String getProcessName(int index) { - WebElement element = findElementByCssSelector(String.format("[id$=':%d:process-name']", index)); - return element.getText(); - } - - public String getSideStepName(int index) { - WebElement element = findElementByCssSelector(String.format("[id$=':%d:side-step-name']", index)); - return element.getText(); - } - - public LendingOverviewPage navigateToLendingOverview() { - clickByCssSelector("[id$='back-to-case-map']"); - waitForElementDisplayed(By.cssSelector("[id$='lending-header']"), true); - return new LendingOverviewPage(); - } - - public LendingDetailPage navigateToPreviousDetail() { - clickByCssSelector("[id$='previous-stage']"); - waitForElementDisplayed(By.cssSelector(String.format("[id$='stage-%d-name']", index - 1)), true); - return new LendingDetailPage(index - 1); - } - - @SuppressWarnings("deprecation") - public LendingDetailPage navigateToNextDetail() { - clickByCssSelector("[id$='next-stage']"); - waitForElementDisplayed(By.cssSelector(String.format("#stage-%d-name", index + 1)), true); - waitAjaxIndicatorDisappear(); - return new LendingDetailPage(index + 1); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingOverviewPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingOverviewPage.java deleted file mode 100644 index 8f7aab8224a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LendingOverviewPage.java +++ /dev/null @@ -1,34 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.userexamples.page.CaseMapPage; - -public class LendingOverviewPage extends TemplatePage { - @Override - protected String getLoadedLocator() { - return "id('lending-header')"; - } - - public String getHearText() { - WebElement element = findElementByCssSelector("[id$='lending-header']"); - return element.getText(); - } - - public String getStageName(int index) { - WebElement element = findElementByCssSelector(String.format("[id$=':%d:stage']", index)); - return element.getText(); - } - - public LendingDetailPage navigateToStageDetail(int index) { - clickByCssSelector(String.format("[id$=':%d:detail-form:detail-stage']", index)); - return new LendingDetailPage(index); - } - - public CaseMapPage startLendingCase() { - clickByCssSelector("#start"); - waitForElementDisplayed(By.cssSelector("input[id$='form:first-name']"), true); - return new CaseMapPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LoginPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LoginPage.java deleted file mode 100644 index 71fcdfa6d8f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/LoginPage.java +++ /dev/null @@ -1,63 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.TestAccount; -import vn.wawa.guitest.base.page.AbstractPage; - -public class LoginPage extends AbstractPage { - - public static final String ID_PROPERTY = "id"; - private static final long LOGIN_TIMEOUT = 60; - private WebElement usernameTextField; - private WebElement passwordField; - private WebElement loginButton; - private WebElement forgotPasswordLink; - private TestAccount testAccount; - - @Override - protected String getLoadedLocator() { - return "id('login:login-form:login-command')"; - } - - public LoginPage() { - waitForPageLoaded(); - this.usernameTextField = findElementByCssSelector("input[id='login:login-form:username']"); - this.passwordField = findElementByCssSelector("input[id='login:login-form:password']"); - this.loginButton = findElementByCssSelector("button[id='login:login-form:login-command']"); - this.forgotPasswordLink = findElementByCssSelector("a[id='login:login-form:forgot-password-link']"); - } - - public LoginPage(TestAccount testAccount) { - this(); - this.testAccount = testAccount; - } - - public void login() { - usernameTextField.sendKeys(testAccount.getUsername()); - passwordField.sendKeys(testAccount.getPassword()); - click(loginButton); - waitForElementDisplayed(By.id("left-menu"), true, LOGIN_TIMEOUT); - } - - public void login(String username, String password) { - usernameTextField.sendKeys(username); - passwordField.sendKeys(password); - click(loginButton); - waitForElementDisplayed(By.id("left-menu"), true, LOGIN_TIMEOUT); - } - - public void forgotPassword() { - click(forgotPasswordLink); - waitForElementDisplayed(By.id("forgot-password:forgot-password-form:send-command"), true, LOGIN_TIMEOUT); - } - - public void waitForEmailAddressIsFocused() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "forgot-password\\:forgot-password-form\\:email", ID_PROPERTY); - } - - public void waitForUsernameInputIsFocused() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "login\\:login-form\\:username", ID_PROPERTY); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/MainMenuPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/MainMenuPage.java deleted file mode 100644 index 6fae373c7bc..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/MainMenuPage.java +++ /dev/null @@ -1,84 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.WaitHelper; - -public class MainMenuPage extends TemplatePage { - - private static String PROCESS_MENU_ITEM_CSS_SELECTOR = ".layout-menu li[role='menuitem'] a.PROCESS"; - - @Override - protected String getLoadedLocator() { - return "id('left-menu')"; - } - - public boolean isProcessesDisplayed() { - return isMenuItemDisplayed("Processes"); - } - - private boolean isMenuItemDisplayed(String menuItemName) { - return findListElementsByCssSelector("li[role='menuitem']").stream() - .filter(element -> element.getText().equals(menuItemName)).findFirst().map(WebElement::isDisplayed) - .orElse(false); - } - - // When hiding all 4 sub menu items: Processes, Cases, Tasks and Statistics. - public boolean isTasksDisplayed() { - return isMenuItemDisplayed("Tasks"); - } - - public boolean isCasesDisplayed() { - return isMenuItemDisplayed("Cases"); - } - - public boolean isStatisticsDisplayed() { - return isMenuItemDisplayed("Statistics"); - } - - public ProcessWidgetPage selectProcessesMenu() { - clickByCssSelector(PROCESS_MENU_ITEM_CSS_SELECTOR); - waitForProcessesPageAfterSelectProcessesCategory(); - return new ProcessWidgetPage(); - } - - public TaskWidgetPage selectTaskMenu() { - WaitHelper.waitForNavigation(this, () -> clickByCssSelector(".layout-menu li[role='menuitem'] a.TASK")); - return new TaskWidgetPage(); - } - - public StatisticWidgetPage selectStatisticDashboard() { - WaitHelper.waitForNavigation(this, () -> clickByCssSelector(".layout-menu li[role='menuitem'] a.STATISTICS")); - return new StatisticWidgetPage(); - } - - public void clickThirdPartyApp() { - waitForElementDisplayed(By.cssSelector("li[class*='thirdparty-menu-item'] > a"), true); - clickByCssSelector("li[class*='thirdparty-menu-item'] > a"); - } - - private void waitForProcessesPageAfterSelectProcessesCategory() { - waitForElementDisplayed(By.id("process-widget:process-search:non-ajax-keyword-filter"), true); - } - - public CaseWidgetPage selectCaseMenu() { - WaitHelper.waitForNavigation(this, () -> clickByCssSelector(".layout-menu li[role='menuitem'] a.CASE")); - return new CaseWidgetPage(); - } - - public WorkingTaskDialogPageOfApplicationMenu selectDashboardMenu() { - clickByCssSelector(".layout-menu li[role='menuitem'] a.DASHBOARD"); - return new WorkingTaskDialogPageOfApplicationMenu(); - } - - public String getProcessMenuItemText() { - openMainMenu(); - return findElementByCssSelector(PROCESS_MENU_ITEM_CSS_SELECTOR).getText(); - } - - public NewDashboardPage backToHomeByClickOnBreadcrumb() { - WaitHelper.waitForNavigation(this, () -> clickByCssSelector("a.ui-icon-home")); - return new NewDashboardPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewAbsencePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewAbsencePage.java deleted file mode 100644 index b1808cfe64c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewAbsencePage.java +++ /dev/null @@ -1,90 +0,0 @@ -package portal.guitest.page; - -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; - -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.DateTimePattern; - -public class NewAbsencePage extends TemplatePage { - - private static final String ABSENCE_ERROR_MESSAGE_SELECTOR = "[id*='absence-messages'] span.ui-messages-error-summary"; - - @Override - protected String getLoadedLocator() { - return "id('absence-dialog_title')"; - } - - public void input(LocalDate absenceFrom, LocalDate absenceTill, String comment) { - inputDate(absenceFrom, "input[id*='absence-start-date']"); - inputDate(absenceTill, "input[id*='absence-end-date']"); - - WebElement commentInput = findElementByCssSelector("textarea[id*='comment']"); - commentInput.sendKeys(comment); - } - - @SuppressWarnings("deprecation") - public void input(String fullName, LocalDate absenceFrom, LocalDate absenceTill, String comment) { - if (StringUtils.isNotEmpty(fullName)) { - String usernameSelector = "input[id*='absence-username']"; - waitForElementDisplayed(By.cssSelector(usernameSelector), true); - WebElement usernameInput = findElementByCssSelector(usernameSelector); - usernameInput.clear(); - usernameInput.sendKeys(fullName); - waitAjaxIndicatorDisappear(); - String itemSelector = "tr[data-item-label*='" + fullName + "'].ui-state-highlight"; - waitForElementDisplayed(By.cssSelector(itemSelector), true); - clickByCssSelector(itemSelector); - waitAjaxIndicatorDisappear(); - } - inputDate(absenceFrom, "input[id*='absence-start-date']"); - inputDate(absenceTill, "input[id*='absence-end-date']"); - WebElement commentInput = findElementByCssSelector("textarea[id*='comment']"); - commentInput.sendKeys(comment); - } - - private void inputDate(LocalDate absenceFrom, String inputCssSelector) { - waitForElementDisplayed(By.cssSelector(inputCssSelector), true); - WebElement fromInput = findElementByCssSelector(inputCssSelector); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateTimePattern.DATE_PATTERN); - fromInput.clear(); - fromInput.sendKeys(Keys.chord(Keys.CONTROL, "a")); - fromInput.sendKeys(Keys.BACK_SPACE); - fromInput.sendKeys(absenceFrom.format(formatter)); - } - - public boolean isErrorMessageDisplayed() { - waitForElementDisplayed(By.cssSelector(ABSENCE_ERROR_MESSAGE_SELECTOR), true); - return true; - } - - public String getErrorMessage() { - WebElement errorMessage = findElementByCssSelector(ABSENCE_ERROR_MESSAGE_SELECTOR); - return errorMessage.getText(); - } - - @SuppressWarnings("deprecation") - public void proceed() { - clickByCssSelector("button[id*='save-absence']"); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void closeAddAbsenceDialog() { - clickByCssSelector("a[id*='close-add-absence-dialog']"); - waitForElementDisplayed(By.cssSelector("[id$='absence-dialog']"), false); - waitAjaxIndicatorDisappear(); - } - - public void enterCommentForAbsence(String comment) { - waitForElementDisplayed(By.cssSelector("[id$='absence-dialog']"), true); - waitForElementDisplayed(By.cssSelector("[id$='absence-form']"), true); - clickByJavaScript(findElementByCssSelector("[id$='absence-form:comment']")); - WebElement commentInput = findElementByCssSelector("textarea[id*='comment']"); - commentInput.sendKeys(comment); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewDashboardPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewDashboardPage.java deleted file mode 100644 index c8c7efdee49..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NewDashboardPage.java +++ /dev/null @@ -1,221 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.WaitHelper; - -public class NewDashboardPage extends TemplatePage { - public final static String PORTAL_HOME_PAGE_URL = "portal/1549F58C18A6C562/DefaultApplicationHomePage.ivp"; - - private static final String CONFIGURATION_DIALOG_ID = "new-widget-configuration-dialog"; - private static final String ADD_WIDGET_DIALOG_ID = "new-widget-dialog"; - private static final String ADD_CUSTOM_WIDGET_BUTTON_ID = "new-custom-widget-dialog-content:0:add-widget"; - private static final String ADD_EXTERNAL_PAGE_WIDGET_BUTTON_ID = "new-widget-dialog-content:1:add-widget"; - private static final String CUSTOM_WIDGET_TYPE_DROPDOWN_ID = "widget-configuration-form:new-widget-configuration-component:custom-widget-type_label"; - private static final String CUSTOM_WIDGET_PROCESS_SELECTION_ID = "widget-configuration-form:new-widget-configuration-component:selected-process"; - private static final String NEWS_FEED_WIDGET_ID = "[class*='js-dashboard-widget-news_']"; - private static final String NEWS_FEED_TITLE_INPUT_ID = "input[id$=':manage-news-tabview:0:news-title']"; - private static final String MANAGE_NEWS_TABVIEW_FORMAT = "[id$=':manage-news-tabview:%s:%s']"; - @Override - protected String getLoadedLocator() { - return "id('dashboard-body')"; - } - - public void startTask(int index) { - String cssSelector = String.format("a[id$='task-component:dashboard-tasks:%d:dashboard-tasks-columns:0:start-task']", index); - waitForElementDisplayed(By.cssSelector(cssSelector), true); - click(By.cssSelector(cssSelector)); - } - - public void waitForTaskNonStartButtonDisplay(int index) { - String cssSelector = String.format("span[id*='task-component:dashboard-tasks:%d']", index); - waitForElementDisplayed(By.cssSelector(cssSelector), true); - } - - public void waitForTaskStartButtonDisplay(int index) { - String cssSelector = String.format("a[id*='task-component:dashboard-tasks:%d']", index); - waitForElementDisplayed(By.cssSelector(cssSelector), true); - } - - public void waitForTaskWidgetEmptyMessage() { - String cssSelector = "tbody[id*='task-component:dashboard-tasks_data']"; - waitForElementDisplayed(By.cssSelector(cssSelector), true); - WebElement taskComponentTable = findElementByCssSelector(cssSelector); - waitForElementDisplayed(taskComponentTable.findElement(By.cssSelector(".ui-datatable-empty-message")), true); - - } - - public void clickAddWidget() { - waitForElementDisplayed(By.cssSelector("button[id='add-button']"), true); - click(By.cssSelector("button[id='add-button']")); - } - - public void addNewCustomWidget() { - clickAddWidget(); - waitForElementDisplayed(By.id("new-widget-dialog"), true); - click(By.id(ADD_CUSTOM_WIDGET_BUTTON_ID)); - waitForElementDisplayed(By.id("new-widget-configuration-dialog"), true); - } - - public void addNewExternalPageWidget() { - clickAddWidget(); - waitForElementDisplayed(By.id("new-widget-dialog"), true); - click(By.id(ADD_EXTERNAL_PAGE_WIDGET_BUTTON_ID)); - waitForElementDisplayed(By.id("new-widget-configuration-dialog"), true); - } - - public void selectCustomWidgetTypeProcess() { - waitForElementDisplayed(By.id(CUSTOM_WIDGET_TYPE_DROPDOWN_ID), true); - click(By.id(CUSTOM_WIDGET_TYPE_DROPDOWN_ID)); - waitForElementDisplayed(By.id("widget-configuration-form:new-widget-configuration-component:custom-widget-type_items"), true); - WebElement typePanel = findElementById("widget-configuration-form:new-widget-configuration-component:custom-widget-type_items"); - click(By.id(typePanel.findElement(By.cssSelector("li:nth-child(2)")).getAttribute("id"))); - } - - public void selectIvyProcessForCustomWidget(String keyword) { - waitForElementDisplayed(By.id(CUSTOM_WIDGET_PROCESS_SELECTION_ID), true); - WebElement processNameTextField = findElementById("widget-configuration-form:new-widget-configuration-component:selected-process_input"); - type(processNameTextField, keyword); - waitForElementDisplayed(By.id("widget-configuration-form:new-widget-configuration-component:selected-process_panel"), true); - click(By.xpath("//*[@id='widget-configuration-form:new-widget-configuration-component:selected-process_panel']/table/tbody/tr")); - waitForElementDisplayed(By.id("widget-configuration-form:new-widget-configuration-component:parameters-fieldset"), true); - } - - public WebElement getConfigurationDialog() { - waitForElementDisplayed(By.id(CONFIGURATION_DIALOG_ID), true); - return findElementById(CONFIGURATION_DIALOG_ID); - } - - public WebElement getFilterOverlayPanel(int index) { - String panelSelector = "div[id$=':filter-overlay-panel-" + index +"']"; - waitForElementDisplayed(By.cssSelector(panelSelector), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-inputfield.saved-filter__search", CLASS_PROPERTY); - return findElementByCssSelector(panelSelector); - } - - public WebElement getAddWidgetDialog() { - waitForElementDisplayed(By.id(ADD_WIDGET_DIALOG_ID), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "new-widget-dialog", ID_PROPERTY); - return findElementById(ADD_WIDGET_DIALOG_ID); - } - - public WebElement getInfoOverlayPanel(int index) { - String panelSelector = "div[id$=':info-overlay-panel-" + index +"']"; - waitForElementDisplayed(By.cssSelector(panelSelector), true); - return findElementByCssSelector(panelSelector); - } - - public void clickWidgetFilter(int index) { - findElementByCssSelector("[id$='filter-sidebar-link-" + index + "']").click(); - waitForElementDisplayed(By.cssSelector("div[id$=':filter-form-" + index + ":widget-filter-content']"), true); - } - - public void clickWidgetInfo(int index) { - findElementByCssSelector("[id$='info-sidebar-link-" + index + "']").click(); - waitForElementDisplayed(By.cssSelector("div[id$=':info-overlay-panel-" + index + "']"), true); - } - - public void waitForTaskWidgetLoading() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-datatable.dashboard-tasks--table", CLASS_PROPERTY); - } - - public void waitForProcessViewerWidgetLoading() { - WaitHelper.assertTrueWithWait(() -> { - var widgetLoading = findElementByCssSelector(".process-viewer-widget-panel [id$='loading']"); - return widgetLoading.getAttribute(CLASS_PROPERTY).contains("u-display-none"); - }); - driver.switchTo().frame("process-viewer"); - waitForElementDisplayed(By.id("sprotty"), true); - driver.switchTo().defaultContent(); - } - - public void waitForStatisticChartWidgetLoading() { - WaitHelper.assertTrueWithWait(() -> { - var taskLoading = findElementByCssSelector(".statistic-chart-widget__content [id$=':loading']"); - return taskLoading.getAttribute(CLASS_PROPERTY).contains("u-display-none"); - }); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-chart statistic-chart-widget__canvas", CLASS_PROPERTY); - } - - public void waitForWidgetInfoLoading(WebElement taskInfoOverlayPanel) { - WaitHelper.assertTrueWithWait(() -> { - var widgetInfo = taskInfoOverlayPanel.findElements(By.cssSelector("[class*='js-loading-']")).get(0); - return widgetInfo.getAttribute(CLASS_PROPERTY).contains("u-display-none"); - }); - } - - public WebElement getProcessViewerWidget() { - return findElementByCssSelector("div[gs-id*='process_viewer']"); - } - - public WebElement getStatisticChartWidget() { - return findElementByCssSelector("div[gs-id*='statistic']"); - } - - public WebElement getFirstNewsFeedWidget() { - waitForElementDisplayed(By.cssSelector(NEWS_FEED_WIDGET_ID), true); - return findElementByCssSelector(NEWS_FEED_WIDGET_ID); - } - - public void waitForNewsWidgetLoadedData() { - getFirstNewsFeedWidget(); - WaitHelper.assertTrueWithWait(() -> { - var widgetLoading = findElementByCssSelector(NEWS_FEED_WIDGET_ID + " [id*=':loading-news_']"); - return widgetLoading.getAttribute(CLASS_PROPERTY).contains("u-display-none"); - }); - waitForElementDisplayed(By.cssSelector("[class*='js-loading-news_']"), false); - waitForElementDisplayed(By.cssSelector("[id$=':news-widget__content']"), true); - } - - public void openManageNewsDialog() { - waitForNewsWidgetLoadedData(); - waitForElementDisplayed(By.cssSelector("a[id$=':add-news-button']"), true); - clickByCssSelector("a[id$=':add-news-button']"); - waitForElementDisplayed(By.cssSelector("[id$=':manage-news-dialog']"), true); - waitForElementDisplayed(By.cssSelector(".management-news__title-input"), true); - waitForElementReallyDisplayed(By.cssSelector(NEWS_FEED_TITLE_INPUT_ID), true); - } - - public WebElement getManageNewsDialog() { - waitForElementDisplayed(By.cssSelector("[id$=':manage-news-dialog']"), true); - waitForElementDisplayed(By.cssSelector(".management-news__title-input"), true); - return findElementByCssSelector("[id$=':manage-news-dialog']"); - } - - public void enterNewsTitle(String newsTitle) { - waitForElementReallyDisplayed(By.cssSelector(NEWS_FEED_TITLE_INPUT_ID), true); - WebElement newsTitleInput = findElementByCssSelector(NEWS_FEED_TITLE_INPUT_ID); - newsTitleInput.clear(); - newsTitleInput.sendKeys(newsTitle); - } - - public String selectNewsLanguage(String languageTag) { - var languageTabClass = "li.ui-tabs-header.news-language-tab-" + languageTag; - findElementByCssSelector(languageTabClass).click(); - return findElementByCssSelector(languageTabClass).getAttribute("data-index"); - } - - public void clickOnTitle(String tabIndex) { - String tabLanguage = "input" + String.format(MANAGE_NEWS_TABVIEW_FORMAT, tabIndex, "news-title"); - waitForElementDisplayed(By.cssSelector(tabLanguage), true); - findElementByCssSelector(tabLanguage).click(); - } - - public WebElement getTranslationOverlayPanel(int index) { - WebElement translationOverlay = findElementByCssSelector( - String.format("div[id$=':%s:overlay-panel-input']", index)); - waitForElementDisplayed(translationOverlay, true); - return translationOverlay; - } - - public void findTranslationButton(String tabIndex) { - findElementByCssSelector(String.format("[id$=':%s:translate-language-button']", tabIndex)).click(); - } - - public String getGlobalFooterInfo() { - waitForElementDisplayed(By.cssSelector("span[id$='server-infor']"), true, 5); - return findElementByCssSelector("span[id$='server-infor']").getText(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NoteHistoryPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NoteHistoryPage.java deleted file mode 100644 index 1fb4af5e7ef..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/NoteHistoryPage.java +++ /dev/null @@ -1,68 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.commons.collections4.CollectionUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class NoteHistoryPage extends TemplatePage { - - private static final String TABLE_ROWS_PATH = "div[id*='notes-table'] table>tbody>tr"; - - @Override - protected String getLoadedLocator() { - return "id('form:notes-table')"; - } - - public int countNotes() { - waitForElementDisplayed(By.cssSelector("div[id*='notes-table']"), true); - return driver.findElements(By.cssSelector(TABLE_ROWS_PATH)).size(); - } - - public int countDoneTasks() { - waitForElementDisplayed(By.cssSelector("div[id*='notes-table']"), true); - List elements = driver.findElements(By.cssSelector(".case-task-note-histories")); - int result = 0; - if (CollectionUtils.isNotEmpty(elements)) { - for (WebElement element : elements) { - if (element.getText().startsWith("Task is done:")) { - result++; - } - } - } - return result; - } - - public String getNoteContentOfRow(int index) { - WebElement firstRow = driver.findElements(By.cssSelector(TABLE_ROWS_PATH)).get(index); - return firstRow.findElements(By.xpath("td")).get(0).getText(); - } - - public String getCaseName() { - return findElementById("form:case-name").getText(); - } - - public String getCaseState() { - return findElementById("form:case-state:case-state-cell").getText(); - } - - public String getCaseId() { - return findElementById("form:case-id").getText(); - } - - public List getNoteAuthors() { - List noteAuthorElements = - findListElementsByCssSelector("td.note-history-fullname-column .name-after-avatar"); - return noteAuthorElements.stream().map(w -> w.getText()).collect(Collectors.toList()); - } - - public void clickOnCheckboxShowSystemNotes() { - findElementByCssSelector("[id$=':show-system-notes-checkbox']").click(); - } - - public void waitForNoteTableDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$=':task-note-table']"), true); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetErrorPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetErrorPage.java deleted file mode 100644 index 1884e24249a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetErrorPage.java +++ /dev/null @@ -1,27 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import vn.wawa.guitest.base.page.AbstractPage; - -public class PasswordResetErrorPage extends AbstractPage { - private static final long PASSWORD_RESET_TIMEOUT = 60; - - private WebElement goForgotPasswordButton; - - @Override - protected String getLoadedLocator() { - return "id('password-reset-error:go-forgot-password-button')"; - } - - public PasswordResetErrorPage() { - waitForPageLoaded(); - this.goForgotPasswordButton = findElementByCssSelector("button[id='password-reset-error:go-forgot-password-button']"); - } - - public void goForgotPassword() { - click(goForgotPasswordButton); - waitForElementDisplayed(By.id("forgot-password:forgot-password-form:send-command"), true, PASSWORD_RESET_TIMEOUT); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetPage.java deleted file mode 100644 index 5d501fb6e7c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordResetPage.java +++ /dev/null @@ -1,61 +0,0 @@ -package portal.guitest.page; - -import org.apache.commons.lang.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import vn.wawa.guitest.base.page.AbstractPage; - -public class PasswordResetPage extends AbstractPage { - private static final long PASSWORD_RESET_TIMEOUT = 60; - - private WebElement newPasswordTextField; - private WebElement passwordConfirmationTextField; - private WebElement resetButton; - - @Override - protected String getLoadedLocator() { - return "id('password-reset:reset-password-form:reset-command')"; - } - - public PasswordResetPage() { - waitForPageLoaded(); - this.newPasswordTextField = findElementByCssSelector("input[id='password-reset:reset-password-form:new-password']"); - this.passwordConfirmationTextField = findElementByCssSelector( - "input[id='password-reset:reset-password-form:password-confirmation']"); - this.resetButton = findElementByCssSelector("button[id='password-reset:reset-password-form:reset-command']"); - } - - public void resetPassword(String newPassword, Boolean strongPasswordEnough) { - newPasswordTextField.sendKeys(newPassword); - passwordConfirmationTextField.sendKeys(newPassword); - click(resetButton); - - if (strongPasswordEnough) { - waitForElementDisplayed(By.id("password-reset:reset-password-form:result-message"), true, PASSWORD_RESET_TIMEOUT); - } else { - waitForElementDisplayedByCssSelector("span[class='ui-messages-error-summary']", (int) PASSWORD_RESET_TIMEOUT); - } - } - - public boolean isNewPasswordNotStrongEnough() { - WebElement element = findElementByCssSelector("span[class='ui-messages-error-summary']"); - return element.getText().equalsIgnoreCase( - "Password must be at least 4 characters long, contain at least 1 lowercase character, contain at least 1 uppercase character, contain at least 1 number, contain at least 1 special character."); - } - - public boolean isReset() { - String resultMessage = findElementByClassName("result-message").getText(); - return StringUtils.isNotBlank(resultMessage); - } - - public void goHome() { - WebElement goHomeButton = findElementById("password-reset:reset-password-form:go-home-button"); - click(goHomeButton); - waitForElementDisplayed(By.id("login:login-form:login-command"), true, PASSWORD_RESET_TIMEOUT); - } - - public void waitForPasswordInputIsFocused() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "password-reset\\:reset-password-form\\:new-password", "id"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordValidationPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordValidationPage.java deleted file mode 100644 index b0feef5973b..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/PasswordValidationPage.java +++ /dev/null @@ -1,67 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class PasswordValidationPage extends TemplatePage { - private static final String PASSWORD_VALIDATION_PAGE_ID = "admin-setting-component:adminTabView:password-validation-component:password-validation-form"; - - public PasswordValidationPage() { - waitForElementDisplayed(By.id(PASSWORD_VALIDATION_PAGE_ID), true); - } - - @Override - protected String getLoadedLocator() { - return "id('admin-setting-component:adminTabView:password-validation-tab')"; - } - - @Override - public boolean isDisplayed() { - return findElementById(PASSWORD_VALIDATION_PAGE_ID).isDisplayed(); - } - - public boolean isPasswordValidationTogglePresent() { - return isElementPresent(By.cssSelector( - "[id$=':password-validation-component:password-validation-form:enable-password-validation-button']")); - } - - public WebElement getPasswordValidationToggle() { - return findElementByCssSelector( - "[id$=':password-validation-component:password-validation-form:enable-password-validation-button']"); - } - - public WebElement getSaveButton() { - return findElementByCssSelector( - "[id$=':password-validation-component:password-validation-form:save-password-validation-btn']"); - } - - public boolean isPasswordValidationToggleChecked() { - return getPasswordValidationToggle().getAttribute("class").contains("ui-toggleswitch-checked"); - } - - public void clickOnPasswordValidationToggle() { - getPasswordValidationToggle().click(); - } - - public boolean isSaveButtonPresent() { - return isElementPresent( - By.cssSelector("[id$=':password-validation-component:password-validation-form:save-password-validation-btn']")); - } - - public boolean isEnableSaveButton() { - return getSaveButton().isEnabled(); - } - - public void clickOnSaveButton() { - getSaveButton().click(); - waitForElementEnabled( - By.cssSelector("[id$=':password-validation-component:password-validation-form:save-password-validation-btn']"), - false, DEFAULT_TIMEOUT); - } - - public boolean isCheckBoxInTableEnabled() { - return findElementByCssSelector( - "[id^='admin-setting-component:adminTabView:password-validation-component:password-validation-form:password-policy-setting']") - .findElement(By.className("ui-chkbox-box")).getAttribute("class").contains("ui-state-active"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessChainPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessChainPage.java deleted file mode 100644 index da5a5272b21..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessChainPage.java +++ /dev/null @@ -1,28 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class ProcessChainPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return COMPONENT_PAGE_LOCATOR; - } - - public boolean isEmptyNextStepButtonDisplay() { - return isElementDisplayed(By.id("form:next-button")); - } - - public void nextStep() { - waitForElementDisplayed(By.id("form:next-button"), true); - click(findElementById("form:next-button")); - } - - public String getCurrentStep() { - waitForElementDisplayed(By.id("form:process-chain-circle-horizontal:component-circle-horizontal"), true); - WebElement step = findElementByCssSelector(".circle-horizontal-process-step.current"); - return step.findElement(By.className("circle-horizontal-step-title")).getText(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessHistoryPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessHistoryPage.java deleted file mode 100644 index dd3f0a9b39c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessHistoryPage.java +++ /dev/null @@ -1,34 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class ProcessHistoryPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return COMPONENT_PAGE_LOCATOR; - } - - public int countCases() { - WebElement caseList = findElementByClassName("ui-datascroller-list"); - return caseList.findElements(By.className("ui-datascroller-item")).size(); - } - - public boolean isEmptyMessageDisplay() { - return isElementDisplayed(By.className("process-history-empty-message")); - } - - public int openDialogAndCountCases() { - click(findElementById("process-history-dialog-button")); - waitForElementDisplayed(By.cssSelector("ul.ui-datascroller-list li div.js-case-item.case-list-item"), true); - WebElement caseList = findElementByClassName("ui-datascroller-list"); - return caseList.findElements(By.className("ui-datascroller-item")).size(); - } - - public WebElement getProcessHistoryDialog() { - click(findElementById("process-history-dialog-button")); - waitForElementDisplayed(By.id("process-history-dialog_content"), true); - return findElementById("process-history-dialog"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessInformationPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessInformationPage.java deleted file mode 100644 index d0f8ca3306b..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessInformationPage.java +++ /dev/null @@ -1,32 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class ProcessInformationPage extends TemplatePage { - - public ProcessInformationPage() {} - - @Override - protected String getLoadedLocator() { - return "//*[contains(@id,'process-information')]"; - } - - public String getProcessName() { - waitForElementDisplayed(By.cssSelector("[id$='header']"), true); - return findElementByCssSelector("[id='header'] > h2 ").getText(); - } - - public String getProcessDescription() { - waitForElementDisplayed(By.cssSelector("[id$='process-description']"), true); - return findElementByCssSelector("[id$='process-description']").getText(); - } - - public void startProcess() { - clickByCssSelector("[id$='start-process-button']"); - } - - @Override - public void back() { - clickByCssSelector("[id$='back-link']"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerComponentPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerComponentPage.java deleted file mode 100644 index 44fe4fbab4a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerComponentPage.java +++ /dev/null @@ -1,20 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class ProcessViewerComponentPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return COMPONENT_PAGE_LOCATOR; - } - - public String getProcessRequestPath() { - return findElementByCssSelector("span[id$=':request-path']").getText(); - } - - public void waitForSprottyToolDisplayed() { - waitForIFrameContentVisible("process-viewer", 15000); - waitForElementDisplayed(By.id("sprotty"), true); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerPage.java deleted file mode 100644 index 49af4981415..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessViewerPage.java +++ /dev/null @@ -1,25 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class ProcessViewerPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('portal-process-viewer-form')"; - } - - public String getProcessRequestPath() { - waitForElementDisplayed(By.id("process-viewer-information"), true); - return findElementByCssSelector("[id$='portal-process-viewer-form'] [id$='request-path']").getText(); - } - - public String getErrorMessage() { - return findElementByCssSelector(".empty-message-text").getText(); - } - - public void waitForSprottyToolDisplayed() { - waitForIFrameContentVisible("process-viewer", 15000); - waitForElementDisplayed(By.id("sprotty"), true); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessWidgetPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessWidgetPage.java deleted file mode 100644 index c35d66d5864..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProcessWidgetPage.java +++ /dev/null @@ -1,504 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.collections4.CollectionUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.WaitHelper; - -public class ProcessWidgetPage extends TemplatePage { - - public static final String IMAGE_MODE = "IMAGE"; - public static final String GRID_MODE = "GRID"; - private static final String ACTIVE_MODE_SELECTOR = "[id$=':process-view-mode:view-mode-selection'] div.ui-button.ui-button-text-only.ui-state-active .ui-button-text"; - private static final String IMAGE_ACTION_BUTTON = "[id$=':%d:image-processes:%d:process-item:image-process-action-component:process-action-button']"; - private static final String GRID_ACTION_BUTTON = "[id$=':%d:grid-processes:%d:process-grid-item:process-item:grid-process-action-component:process-action-button']"; - private static final String IMAGE_EDIT_PROCESS_LINK = "[id$=':%d:image-processes:%d:process-item:image-process-action-component:edit-process']"; - private WebElement switchModeButton; - private WebElement liveSearchTextField; - private WebElement processWidget; - private String processWidgetId; - - - public ProcessWidgetPage() { - this("process-widget"); - } - - public ProcessWidgetPage(String processWidgetId) { - this.processWidgetId = processWidgetId; - processWidget = findElementById(this.processWidgetId); - } - - @Override - protected String getLoadedLocator() { - return "//*[contains(@id,'process-list')]"; - } - - public void waitAndStartProcess(String processName) { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> { - if (findListElementsByCssSelector(".js-no-found-processes.u-display-none").get(0).isDisplayed()) { - refresh(); - return false; - } else { - return true; - } - }); - - startProcess(processName); - } - - public void startProcess(String processName) { - WebElement processItemElement = getProcess(processName); - processItemElement.click(); - } - - public WebElement getProcess(String processName) { - WebElement processListElement = findElementById(processWidgetId + ":process-list"); - if (isImageModeActivated()) { - return getStartImageProcess(processName, processListElement); - } - return findChildElementByXpathExpression(processListElement, "//a[.//text() = '" + processName + "']"); - } - - public WebElement getStartImageProcess(String processName, WebElement processListElement) { - WebElement startProcessItemElement = null; - List processItems = findChildElementsByCssSelector(processListElement, ".js-process-start-list-item"); - for (WebElement process : processItems) { - WebElement processNameElement = findChildElementByCssSelector(process, ".js-process-start-list-item-name"); - if (processNameElement.getText().equalsIgnoreCase(processName)) { - startProcessItemElement = findChildElementByCssSelector(process, "[id$=':process-item:start-button']"); - break; - } - } - return startProcessItemElement; - } - - public WebElement getProcessItem(String processName) { - WebElement processItemElement = null; - List processItems = findListElementsByClassName("js-process-start-list-item"); - for (WebElement process : processItems) { - processItemElement = findChildElementByCssSelector(process, ".js-process-start-list-item-name"); - if (processItemElement.getText().equalsIgnoreCase(processName)) { - processItemElement = process; - break; - } - } - return processItemElement; - } - - public ExpressProcessPage editExpressWF(String wfName) { - int numberOfRefesh = 5; - for (int i = 0; i < numberOfRefesh; i++) { - waitForElementDisplayed(By.id(processWidgetId + ":process-search:non-ajax-keyword-filter"), true); - enterSearchKeyword(wfName); - if (isImageModeActivated()) { - WebElement processForm = findElementByCssSelector("form.image-view-form.is-express"); - var processFormID = processForm.getAttribute("id"); - clickByCssSelector("[id$='" + processFormID + ":image-process-action-component:process-action-button']"); - waitForElementDisplayed(By.cssSelector(".process-action-menu.ui-connected-overlay-enter-done"), true); - if (isElementDisplayed(By.cssSelector("div[id$='"+ processFormID + ":image-process-action-component:process-action-menu']"))) { - WebElement actionMenu = findElementByCssSelector("div[id$='"+ processFormID + ":image-process-action-component:process-action-menu']"); - WebElement icon = findChildElementByCssSelector(actionMenu, "a[id$=':process-item:image-process-action-component:edit-process']"); - icon.click(); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:edit-process-dialog']"), true); - clickByCssSelector("a[id$='process-widget:edit-process-form:edit-express-workflow']"); - break; - } - } else { - if (isElementDisplayed(By.cssSelector("[id$='edit-express-workflow']"))) { - click(By.cssSelector("[id$='edit-express-workflow']")); - break; - } - } - - refresh(); - } - return new ExpressProcessPage(); - } - - public boolean isProcessDisplay(String processName) { - return getProcess(processName) !=null; - } - - public boolean isNoProcessFound() { - return isElementPresent(By.xpath("//span[@id='process-widget:no-found-processes']")); - } - - public boolean isProcessGroupDisplay(String processGroupCharacter) { - if (isImageModeActivated()) { - List webElements = findListElementsByClassName("js-grid-process-index-group"); - return webElements.stream().anyMatch(processItem -> processItem.isDisplayed() && processItem.getAttribute("class").endsWith(processGroupCharacter)); - } - List indexGroup = findListElementsByXpath("//legend[@class='ui-fieldset-legend ui-corner-all ui-state-default']"); - return indexGroup.stream().anyMatch(item -> processGroupCharacter.equals(item.getText())); - } - - public String getProcessNameFromDefaultProcessList(int index) { - WebElement defaultProcessList = findElementById(processWidgetId + ":user-default-process-list"); - String id = index + ":process-item-form:process-name"; - String name = findChildElementByCssSelector(defaultProcessList, "span[id*='" + id + "']").getText(); - return name; - } - - public void clickEditSwitchLink() { - waitForElementDisplayed(By.cssSelector("[id$='editing-switch-command']"), true, DEFAULT_TIMEOUT); - click(findElementByCssSelector("[id$='editing-switch-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void clickSaveProcess() { - WebElement deleteProcessLink = findChildElementByCssSelector(processWidget, "[id$='save-process-command']"); - click(deleteProcessLink); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public AddNewExternalLinkDialog openNewExternalLinkDialog() { - waitForElementDisplayed(By.id(processWidgetId + ":add-external-link-command"), true); - click(By.id("process-widget:add-external-link-command")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "process-widget\\\\:add-external-link-form\\\\:external-link-name", ID_PROPERTY); - return new AddNewExternalLinkDialog(); - } - - private List findDeleteIcons() { - waitForElementDisplayed(By.id(processWidgetId + ":process-list"), true); - WebElement processList = findElementById(processWidgetId + ":process-list"); - List deleteItems = processList.findElements(By.cssSelector("a[id*='process-delete-link']")); - return deleteItems; - } - - public boolean isDeleteProcessItemSelected(int itemIndex) { - WebElement deleteItem = findDeleteIcons().get(itemIndex); - - WebElement deleteItemCheckBox = findChildElementByClassName(deleteItem, "si"); - String styleClass = deleteItemCheckBox.getAttribute("class"); - return styleClass.contains("si-undo"); - } - - public void checkDeleteItem(int itemIndex) { - List deleteCheckboxes = findDeleteIcons(); - WebElement checkBox = deleteCheckboxes.get(itemIndex); - click(checkBox); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void clickSortDefaultProcessByName() { - waitForElementDisplayed(By.cssSelector("[id$='default-process-name-sort-command']"), true, DEFAULT_TIMEOUT); - click(findElementByCssSelector("[id$='default-process-name-sort-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public boolean isExpandedMode() { - loadLiveSearchTextField(); - return liveSearchTextField.isDisplayed(); - } - - public boolean isCompactMode() { - List findElements = driver.findElements(By.id(processWidgetId + ":process-search:non-ajax-keyword-filter")); - return findElements.isEmpty(); - } - - public boolean isImageModeActivated() { - List findElements = driver.findElements(By.cssSelector("[id$=':image-process-container']")); - return !findElements.isEmpty(); - } - - public void expand() { - loadSwitchModeButton(); - click(switchModeButton); - waitForElementDisplayed(By.id(processWidgetId + ":process-search:non-ajax-keyword-filter"), true, DEFAULT_TIMEOUT); - waitForElementDisplayed(By.className("js-loading-process-list"), false); - waitForElementDisplayed(By.className("js-process-start-list-container"), true); - } - - private void loadSwitchModeButton() { - switchModeButton = findElementById(processWidgetId + ":process-link:process-link-label"); - } - - private void loadLiveSearchTextField() { - liveSearchTextField = findElementById(processWidgetId + ":process-search:non-ajax-keyword-filter"); - } - - public void enterSearchKeyword(String keyword) { - liveSearchTextField = findElementById(processWidgetId + ":process-search:non-ajax-keyword-filter"); - type(liveSearchTextField, keyword); - } - - public class AddNewExternalLinkDialog { - private final String EXTERNAL_LINK_NAME_INPUT_CSS_SELECTOR = "input[id$=':add-external-link-form:external-link-name']"; - private final String EXTERNAL_LINK_INPUT_CSS_SELECTOR = "input[id$=':add-external-link-form:external-link']"; - private final String ADD_EXTERNAL_LINK_BUTTON_INPUT_CSS_SELECTOR = "button[id$='adding-new-external-link-command']"; - - private AddNewExternalLinkDialog() {} - - public void inputDataForPrivateExternalLink(String processName, String processLink) { - inputExternalLinkName(processName); - inputExternalLink(processLink); - } - - public void inputDataForPublicExternalLink(String processName, String processLink, String rolePermission) { - inputExternalLinkName(processName); - inputExternalLink(processLink); - selectExternalLinkType(true); - selectExternalLinkRolePermission(rolePermission); - } - - public void inputExternalLinkName(String name) { - WebElement externalLinkInputField = findDisplayedElementByCssSelector(EXTERNAL_LINK_NAME_INPUT_CSS_SELECTOR); - externalLinkInputField.sendKeys(name); - } - - public void inputExternalLink(String link) { - WebElement externalLinkInputField = findDisplayedElementByCssSelector(EXTERNAL_LINK_INPUT_CSS_SELECTOR); - externalLinkInputField.sendKeys(link); - } - - public void selectExternalLinkType(boolean isPublic) { - if (isPublic) { - WebElement externalCheckboxLabel = findElementByCssSelector("label[for$=':add-external-link-form:external-link-type-radio:1']"); - externalCheckboxLabel.click(); - } - } - - public void selectExternalLinkRolePermission(String rolePermission) { - WebElement rolePermissionInput = findDisplayedElementByCssSelector( - "[id$='process-widget:add-external-link-form:role-autocomplete-for-creating-external-link_input"); - rolePermissionInput.sendKeys(rolePermission); - waitForElementDisplayed(By.cssSelector("span[id$='process-widget:add-external-link-form:role-autocomplete-for-creating-external-link_panel']"), true); - rolePermissionInput.sendKeys(Keys.DOWN); - rolePermissionInput.sendKeys(Keys.ENTER); - } - - public void submitForm() { - WebElement submitButton = findElementByCssSelector(ADD_EXTERNAL_LINK_BUTTON_INPUT_CSS_SELECTOR); - submitButton.click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - } - - public ExpressProcessPage openExpressPage() { - waitForElementDisplayed(By.id(processWidgetId + ":create-express-workflow"), true); - click(By.id("process-widget:create-express-workflow")); - return new ExpressProcessPage(); - } - - public boolean isProcessEmpty() { - return isElementDisplayed(By.id("search-results-tabview:process-results:full-process-empty-message")); - } - - public boolean hasCreateNewExpressWorkflowLink() { - return isElementPresent(By.id("process-widget:create-express-workflow")); - } - - @SuppressWarnings("deprecation") - public void deleteExternalLinkByFieldsetIndexAndIndex(int fieldsetIndex, int index) { - String deleteExternalLinkIconCssSelector = String.format("a[id$='%d:processes:%d:process-item-form:delete-external-link']", fieldsetIndex, index); - WebElement deleteExternalIcon = findElementByCssSelector(deleteExternalLinkIconCssSelector); - deleteExternalIcon.click(); - waitAjaxIndicatorDisappear(); - findElementByCssSelector("button[id$=':remove-process-command']").click(); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public ExampleOverviewPage openExampleOverviewPage(String exampleProcessName) { - click(getProcess(exampleProcessName)); - waitAjaxIndicatorDisappear(); - return new ExampleOverviewPage(); - } - - public WebElement getAddExternalLinkDialog() { - return findElementById("process-widget:add-external-link-dialog"); - } - - public WebElement navigateToProcessIndex(String character) { - WebElement processIndex = findElementByCssSelector(".js-process-nav-item.js-process-starts-with-" + character); - processIndex.click(); - return processIndex; - } - - public void waitUtilProcessWidgetDisplayed() { - waitForElementDisplayed(By.id("process-widget"), true); - waitForElementDisplayed(By.className("js-loading-process-list"), false); - waitForElementDisplayed(By.className("js-process-start-list-container"), true); - } - - public String getCurrentViewMode() { - waitForElementDisplayed( - By.cssSelector("[id$=':process-view-mode:view-mode-selection'] div.ui-button.ui-button-text-only.ui-state-active"), - true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, - "process-widget\\\\:process-view-mode\\\\:view-mode-selection", - ID_PROPERTY); - return findElementByCssSelector(ACTIVE_MODE_SELECTOR).getText(); - } - - public void clickOnProcessEditLink(int index) { - clickByCssSelector(String.format("[id$=':%d:grid-processes:0:process-grid-item:process-item:edit-link']", index)); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:edit-process-dialog']"), true); - } - - public WebElement getProcessEditMenu(int index) { - return findElementByCssSelector(String.format(IMAGE_EDIT_PROCESS_LINK, 0, index)); - } - - public void clickOnProcessEditMenu(int index) { - clickByCssSelector(String.format(IMAGE_EDIT_PROCESS_LINK, 0, index)); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:edit-process-dialog']"), true); - } - - public WebElement getEditProcessDialog() { - return findElementByCssSelector("[id$='process-widget:edit-process-dialog']"); - } - - public void changeProcessIcon() { - clickByCssSelector("a[id^='process-widget:edit-process-form:edit-process-icon']"); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:edit-process-form:edit-process-icon:select-icon-dialog']"), true); - clickByCssSelector("[id$=':0:awesome-icon']"); - - } - - public void addNewRolePermission(String rolePermission) { - waitForElementDisplayed(By.cssSelector("span[id='process-widget:edit-process-form:role-permissions-editor-for-external-link_display'] a.si.si-graphic-tablet-drawing-pen"), true); - clickByCssSelector("span[id='process-widget:edit-process-form:role-permissions-editor-for-external-link_display'] a.si.si-graphic-tablet-drawing-pen"); - WebElement rolePermissionInput = findDisplayedElementByCssSelector( - "[id$='process-widget:edit-process-form:role-autocomplete-for-editing-external-link_input']"); - rolePermissionInput.sendKeys(rolePermission); - waitForElementDisplayed(By.cssSelector("span[id$='process-widget:edit-process-form:role-autocomplete-for-editing-external-link_panel']"), true); - rolePermissionInput.sendKeys(Keys.DOWN); - rolePermissionInput.sendKeys(Keys.ENTER); - WebElement savePermissionButton = - findDisplayedElementByCssSelector("span[id='process-widget:edit-process-form:role-permissions-editor-for-external-link_editor'] button.ui-button-icon-only.ui-inplace-save"); - savePermissionButton.click(); - } - - public void saveEditProcessDialog() { - clickByCssSelector("[id$='process-widget:save-process-command']"); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:edit-process-dialog']"), false); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public String getProcessItemIcon(int index) { - WebElement processItem = findElementByCssSelector(String.format("[id$='grid-process-group-alphabet:%d:grid-processes:0:process-grid-item:process-item']", index)); - return processItem.findElement(By.id("icon")).getAttribute("class"); - } - - public void deleteGridProcess(int index) { - clickByCssSelector(String.format("[id$=':%d:grid-processes:0:process-grid-item:process-item:grid-process-action-component:delete-process']", index)); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:remove-process-workflow-dialog']"), true); - clickByCssSelector("[id$='delete-process-workflow-form:remove-process-command']"); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:remove-process-workflow-dialog']"), false); - } - - public void clickMoreInformationLink(String processName) { - WebElement processItem = getProcessItem(processName); - processItem.findElement(By.cssSelector(".more-information")).click(); - } - - public void waitForImageProcessListDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$='process-widget:image-process-container']"), true); - } - - public void waitForGridProcessListDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$='process-widget:grid-process-container']"), true); - } - - public void waitForCompactProcessListDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$='process-widget:process-list']"), true); - } - - public void selectViewMode(String viewMode) { - waitForElementDisplayed(By.cssSelector("[id$='process-widget:process-view-mode:view-mode-selection']"), true); - WebElement viewModeElement = findElementByCssSelector("[id$='process-widget:process-view-mode:view-mode-selection']"); - List webElements = viewModeElement.findElements(By.cssSelector("span.ui-button-text.ui-c")); - if (CollectionUtils.isNotEmpty(webElements)) { - for(WebElement webElement: webElements) { - if(webElement.getText().equalsIgnoreCase(viewMode)) { - webElement.click(); - WaitHelper.assertTrueWithWait(() -> { - return findElementByCssSelector(ACTIVE_MODE_SELECTOR) - .getText().equalsIgnoreCase(viewMode); - }); - WaitHelper.assertTrueWithWait(() -> { - if (IMAGE_MODE.equalsIgnoreCase(viewMode)) { - return findElementByCssSelector(".process-group.image-process-container").isDisplayed(); - } - if (GRID_MODE.equalsIgnoreCase(viewMode)) { - return findElementByCssSelector(".process-group.grid-process-container").isDisplayed(); - } - return true; - }); - return; - } - } - } - } - - public void clickMoreButtonOfFirstImageProcess() { - findListElementsByCssSelector("[id$=':process-item:image-process-action-component:process-action-button']") - .stream().filter(WebElement::isDisplayed) - .filter(WebElement::isEnabled).findFirst().ifPresent(firstActionButton -> { - clickByJavaScript(firstActionButton); - }); - } - - public WebElement getMoreMenuButtonOfImageProcess(int index) { - return findElementByCssSelector(String.format(IMAGE_ACTION_BUTTON, index, 0)); - } - - public void waitForMenuActionsDisplayed() { - waitForElementDisplayed(By.cssSelector(String.format(IMAGE_ACTION_BUTTON, 0, 0)), true); - } - - public void clickMoreButtonOfFirstGridProcess() { - waitForElementDisplayed(By.cssSelector(String.format(GRID_ACTION_BUTTON, 0, 0)), true); - clickByCssSelector(String.format(GRID_ACTION_BUTTON, 0, 0)); - } - - public void waitForMenuActionsOnGridModeDisplayed() { - waitForElementDisplayed( - By.cssSelector( - "[id$='process-widget:grid-process-group-alphabet:0:grid-processes:0:process-grid-item:process-item:process-delete']"), - true); - } - - public void clickMoreButtonOfGridProcess(String processName) { - var processItem = getProcessItemForm(processName); - var actionButtonID = processItem.getAttribute(ID_PROPERTY).concat(":grid-process-action-component:process-action-button"); - clickByCssSelector(String.format("[id$='%s']", actionButtonID)); - waitForElementDisplayed(By.cssSelector(String - .format("[id$='%s']", processItem.getAttribute(ID_PROPERTY).concat(":grid-process-action-component:process-action-menu"))), - true); - } - - public WebElement getProcessItemForm(String processName) { - WebElement processItemElement = null; - List processItems = findListElementsByCssSelector(".js-process-start-list-item form"); - for (WebElement process : processItems) { - processItemElement = findChildElementByCssSelector(process, ".js-process-start-list-item-name"); - if (processItemElement.getText().equalsIgnoreCase(processName)) { - processItemElement = process; - break; - } - } - return processItemElement; - } - - public void deleteGridProcess(String processName) { - var processItem = getProcessItemForm(processName); - waitForElementDisplayed(By.cssSelector(String.format("[id$='%s']", - processItem.getAttribute(ID_PROPERTY).concat(":grid-process-action-component:process-action-menu"))), - true); - clickByCssSelector(String.format("[id$='%s']", processItem.getAttribute(ID_PROPERTY).concat(":grid-process-action-component:delete-process"))); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:remove-process-workflow-dialog']"), true); - clickByCssSelector("[id$='delete-process-workflow-form:remove-process-command']"); - waitForElementDisplayed(By.cssSelector("[id$='process-widget:remove-process-workflow-dialog']"), false); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProjectVersionPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProjectVersionPage.java deleted file mode 100644 index b46ea455de1..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/ProjectVersionPage.java +++ /dev/null @@ -1,28 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class ProjectVersionPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('project-version:engine-version-label')"; - } - - public boolean isEngineVersionDisplayed() { - return isElementDisplayed(By.id("project-version:engine-version-label")); - } - - public boolean isPortalVersionDisplayed() { - return isElementDisplayed(By.id("project-version:portal-version-label")); - } - - public boolean isFirstProjectDisplayed() { - return isElementDisplayed(By.id("project-version:application-list:0:application-project-version-table:0:project-name")); - } - - public WebElement getProjectVersionDialog() { - return findElementById("project-info-dialog"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleManagementPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleManagementPage.java deleted file mode 100644 index 308f1f92539..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleManagementPage.java +++ /dev/null @@ -1,216 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.stream.Collectors; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.WaitHelper; - -public class RoleManagementPage extends TemplatePage { - - private static final String ROLE_ASSINGMENT_PAGE_ID = - "admin-setting-component:adminTabView:role-management-component:role-management-form"; - - public RoleManagementPage() { - waitForElementDisplayed(By.id(ROLE_ASSINGMENT_PAGE_ID), true); - } - - @Override - protected String getLoadedLocator() { - return "id('admin-setting-component:adminTabView:role-management-tab')"; - } - - @Override - public boolean isDisplayed() { - return findElementById(ROLE_ASSINGMENT_PAGE_ID).isDisplayed(); - } - - public boolean isCreateNewRoleButtonPresent() { - return isElementPresent(By.cssSelector("[id$=':role-management-component:role-management-form:create-role-button']")); - } - - public void openRoleCreationDialog() { - clickByCssSelector("[id$=':role-management-component:role-management-form:create-role-button']"); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:role-details-dialog_content']"), true); - } - - public WebElement getRoleInfoDialogContent() { - return findElementByCssSelector("[id$=':role-management-component:role-details-dialog_content']"); - } - - public void clickOnSaveRoleButtonDialog() { - clickByCssSelector("[id$=':role-management-component:save-role-configuration']"); - waitForElementDisplayed(getRoleDetailsDialog(), false); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:role-management-message_container']"), true); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:role-management-message_container']"), false); - } - - public void createNewRoleWithData(String parentRole, String roleName, String roleDisplayName, String roleDescription, - List members) { - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:manage-role-details-form']"), true); - - // Fill parent data - var parentRoleInput = findElementByCssSelector("[id$=':manage-role-details-form:parent-role:parent-role-selection_input']"); - parentRoleInput.clear(); - parentRoleInput.sendKeys(parentRole); - waitForElementDisplayed(By.cssSelector("[id$=':manage-role-details-form:parent-role:parent-role-selection_panel']"), true); - var roleSelectionPanel = findElementByCssSelector("[id$=':manage-role-details-form:parent-role:parent-role-selection_panel']"); - var parentRoleOption = roleSelectionPanel.findElements(By.cssSelector(".ui-autocomplete-item.ui-autocomplete-row")).get(0); - click(parentRoleOption); - waitForElementDisplayed(By.cssSelector("[id$=':manage-role-details-form:parent-role:parent-role-selection_panel']"), false); - - // Fill role name data - var roleNameInput = findElementByCssSelector("[id$=':manage-role-details-form:role-name']"); - roleNameInput.sendKeys(roleName); - - enterRoleAdditionalInformation(roleDisplayName, roleDescription); - assignUsersToRole(members); - } - - public String getRoleNamesInRoleTreeTable() { - return getRoleTreeTable().findElements(By.cssSelector("tbody tr.role span[id$=':role-username']")).stream() - .map(WebElement::getText).collect(Collectors.joining(";")); - } - - public String getRoleDisplayNameInRoleTreeTable() { - return getRoleTreeTable().findElements(By.cssSelector("tbody tr.role span[id$=':role-displayname']")).stream() - .map(WebElement::getText).collect(Collectors.joining(";")); - } - - public String getTotalUsersOfRoleInRoleTreeTable(String roleName) { - for (var row : getRolesOnTheTreeTable()) { - if (row.findElement(By.cssSelector("span[id$=':role-username']")).getText().equalsIgnoreCase(roleName)) { - return row.findElement(By.cssSelector("span[id$=':role-assigned-users-text']")).getText(); - } - } - return ""; - } - - public WebElement getDeleteActionEnableForRole(String roleName) { - return findActionForRoleByName(roleName, "delete-role-link"); - } - - public void deleteRole(String roleName) { - var deleteLink = getDeleteActionEnableForRole(roleName); - click(deleteLink); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:delete-role-dialog']"), true); - clickByCssSelector("button[id$=':role-management-component:yes-button']"); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:delete-role-dialog']"), false); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:role-management-message_container']"), true); - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:role-management-message_container']"), false); - } - - public WebElement getEditActionEnableForRole(String roleName) { - return findActionForRoleByName(roleName, "edit-role-link"); - } - - public void clickOnEditRole(String roleName) { - var editLink = getEditActionEnableForRole(roleName); - click(editLink); - waitForElementDisplayed(getRoleDetailsDialog(), true); - } - - public WebElement getAssigningUsersActionEnableForRole(String roleName) { - return findActionForRoleByName(roleName, "assign-users-to-role-link"); - } - - public WebElement findActionForRoleByName(String roleName, String actionId) { - for (var role : getRolesOnTheTreeTable()) { - var roleNameColumn = role.findElement(By.cssSelector("td.role-name-column span[id$=':role-username']")); - if (roleNameColumn.getText().equalsIgnoreCase(roleName)) { - return role.findElement(By.cssSelector("td.role-actions-column [id$=':" + actionId + "']")); - } - } - return null; - } - - private List getRolesOnTheTreeTable() { - return getRoleTreeTable().findElements(By.cssSelector("tbody tr.role")); - } - - private WebElement getRoleTreeTable() { - return findElementByCssSelector("[id$=':role-management-form:role-tree-table']"); - } - - public void clickOnCancelLinkOfRoleDialog() { - clickByCssSelector("[id$=':role-management-component:cancel-link']"); - waitForElementDisplayed(getRoleDetailsDialog(), false); - } - - private By getRoleDetailsDialog() { - return By.cssSelector("[id$=':role-management-component:role-details-dialog']"); - } - - public void enterRoleAdditionalInformation(String roleDisplayName, String roleDescription) { - waitForElementDisplayed(By.cssSelector("[id$=':role-management-component:role-details-dialog_title']"), true); - // Fill role display name data - var roleDisplayNameInput = findElementByCssSelector("[id$=':manage-role-details-form:role-display-name']"); - roleDisplayNameInput.clear(); - roleDisplayNameInput.sendKeys(roleDisplayName); - - // Fill role description data - var roleDescriptionInput = findElementByCssSelector("[id$=':manage-role-details-form:role-description']"); - roleDescriptionInput.clear(); - roleDescriptionInput.sendKeys(roleDescription); - } - - public void clickOnAssignUsersToRole(String roleName) { - var assignUsersLink = getAssigningUsersActionEnableForRole(roleName); - click(assignUsersLink); - waitForElementDisplayed(getRoleDetailsDialog(), true); - } - - public void assignUsersToRole(String roleName, List members) { - clickOnAssignUsersToRole(roleName); - assignUsersToRole(members); - } - - private void assignUsersToRole(List members) { - for (var userName : members) { - var usersAssignmentInput = findElementByCssSelector("[id$=':manage-role-details-form:user-assignment-selection:user-selection_input']"); - usersAssignmentInput.clear(); - usersAssignmentInput.sendKeys(userName); - waitForElementDisplayed(By.cssSelector("[id$=':manage-role-details-form:user-assignment-selection:user-selection_panel"), true); - var userSelectionPanel = findElementByCssSelector("[id$=':manage-role-details-form:user-assignment-selection:user-selection_panel"); - var userOption = userSelectionPanel.findElements(By.cssSelector(".ui-autocomplete-item.ui-autocomplete-row")).get(0); - click(userOption); - - waitForElementDisplayed(By.cssSelector("[id$=':manage-role-details-form:user-assignment-selection:user-selection_panel"), false); - waitForElementEnabled(By.cssSelector("button[id$=':manage-role-details-form:add-new-user']"), true, DEFAULT_TIMEOUT); - clickByCssSelector("button[id$=':manage-role-details-form:add-new-user']"); - waitForElementEnabled(By.cssSelector("button[id$=':manage-role-details-form:add-new-user']"), false, DEFAULT_TIMEOUT); - } - } - - public void clickOnCloseAssignUsersButton() { - clickByCssSelector("button[id$=':role-management-component:cancel-update-users']"); - waitForElementDisplayed(getRoleDetailsDialog(), false); - } - - public void filterRoleTreeTableByRoleName(String roleName) { - var roleNames = getRoleNamesInRoleTreeTable(); - var filterInput = getRoleTreeTable().findElement(By.cssSelector("input[id$=':role-management-form:role-tree-table:global-filter']")); - filterInput.clear(); - filterInput.sendKeys(roleName); - WaitHelper.assertTrueWithWait(() -> { - return !roleNames.equalsIgnoreCase(getRoleNamesInRoleTreeTable()); - }); - } - - public void removeAllUsersOfRole(String roleName) { - clickOnAssignUsersToRole(roleName); - waitForElementDisplayed(By.cssSelector("[id$=':manage-role-details-form:users-of-role-table']"), true); - removeUserOfRole(0); - } - - private void removeUserOfRole(int index) { - waitForElementDisplayed(By.cssSelector("[id$=':manage-role-details-form:users-of-role-table_data']"), true); - if (isElementDisplayed(By.cssSelector("a[id$=':delete-user-link']")) - && isElementEnabled(By.cssSelector("a[id$=':delete-user-link']"))) { - click(findListElementsByCssSelector("a[id$=':delete-user-link']").get(index)); - removeUserOfRole(0); - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleSelectionComponentPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleSelectionComponentPage.java deleted file mode 100644 index 2a0dc6b5989..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/RoleSelectionComponentPage.java +++ /dev/null @@ -1,86 +0,0 @@ -package portal.guitest.page; - -import java.util.List; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class RoleSelectionComponentPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('form:assign-selected-role-btn')"; - } - - public WebElement getDefaultRoleSelectionComponent() { - return findElementById("default-role-selection-component"); - } - - public WebElement getFloatingLabelAndExcludeRoleSelectionComponent() { - return findElementById("floating-label-and-exclude-role-component"); - } - - public WebElement getRoleFromDefinedRoleSelectionComponent() { - return findElementById("role-from-defined-role-component"); - } - - public WebElement getAjaxEventRoleSelectionComponent() { - return findElementById("item-select-with-ajax-event-component"); - } - - public String selectFirstItemForDefaultRoleSelectionComponent(String keyword) { - WebElement roleElement = selectRoleSelection("default-role-autocomplete", keyword); - click(roleElement); - waitForElementDisplayed(By.cssSelector("span[id$='default-role-autocomplete_panel']"), false); - return roleElement.getCssValue("data-item-value"); - } - - public String getDefaultRoleSelection() { - return findElementByCssSelector("input[id$='default-role-autocomplete_hinput']").getCssValue("value"); - } - - public String selectFirstItemForRoleFromDefinedRoleSelectionComponent(String keyword) { - WebElement roleElement = selectRoleSelection("role-from-defined-role-autocomplete", keyword); - click(roleElement); - waitForElementDisplayed(By.cssSelector("span[id$='role-from-defined-role-autocomplete_panel']"), false); - return roleElement.getCssValue("data-item-value"); - } - - public String getRoleFromDefinedRoleSelection() { - return findElementByCssSelector("input[id$='role-from-defined-role-autocomplete_hinput']").getCssValue("value"); - } - - public String selectFirstItemForFloatingLabelAndExcludeRoleSelectionComponent(String keyword) { - WebElement roleElement = selectRoleSelection("floating-label-and-exclude-role-autocomplete", keyword); - click(roleElement); - waitForElementDisplayed(By.cssSelector("span[id$='floating-label-and-exclude-role-autocomplete_panel']"), false); - return roleElement.getCssValue("data-item-value"); - } - - public String getFloatingLabelAndExcludeRoleSelection() { - return findElementByCssSelector("input[id$='floating-label-and-exclude-role-autocomplete_hinput']").getCssValue("value"); - } - - public String selectFirstItemForAjaxEventRoleSelectionComponent(String keyword) { - WebElement roleElement = selectRoleSelection("item-select-event-for-role-selection", keyword); - click(roleElement); - waitForElementDisplayed(By.cssSelector("[id$='item-select-event-for-role-selection-message_info-detail']"), true); - return roleElement.getCssValue("data-item-value"); - } - - public String getAjaxEventRoleSelection() { - return findElementByCssSelector("input[id$='item-select-event-for-role-selection_hinput']").getCssValue("value"); - } - - public void openSelectionPanelForAjaxEventRoleSelectionComponent(String keyword) { - type(By.cssSelector("input[id$='item-select-event-for-role-selection_input']"), keyword); - waitForElementDisplayed(By.cssSelector("span[id$='item-select-event-for-role-selection_panel']"), true); - } - - private WebElement selectRoleSelection(String componentId, String keyword) { - type(By.cssSelector("input[id$='"+componentId+"_input']"), keyword); - waitForElementDisplayed(By.cssSelector("span[id$='"+componentId+"_panel']"), true); - List selectionItems = findElementByCssSelector("span[id$='"+componentId+"_panel']").findElements(By.className("ui-autocomplete-item")); - return selectionItems.get(0); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SearchResultPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SearchResultPage.java deleted file mode 100644 index 834e0e22033..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SearchResultPage.java +++ /dev/null @@ -1,153 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class SearchResultPage extends TemplatePage { - - private final String INFO_EXPRESS_WORKFlOW = "span[id$='info-workflow']"; - private final String EDIT_EXPRESS_WORKFlOW = "a[id$='edit-express-workflow']"; - private final String DELETE_EXPRESS_WORKFlOW = "a[id$='delete-express-workflow']"; - private final String EXPRESS_PROCESS_LOGO = "span[id$='express-process-logo']"; - - @Override - protected String getLoadedLocator() { - return "id('search-results-tabview')"; - } - - @SuppressWarnings("deprecation") - public void openTaskTab() { - click(By.cssSelector("li[class*='task-tab-title']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void openCaseTab() { - click(By.cssSelector("li[class*='case-tab-title']")); - waitAjaxIndicatorDisappear(); - } - - public void startProcess(String name) { - ProcessWidgetPage processWidgetPage = getProcessWidget(); - if (processWidgetPage.isImageModeActivated()) { - WebElement processListElement = findElementById("search-results-tabview:process-results"); - WebElement processItemElement = processWidgetPage.getStartImageProcess(name, processListElement); - processItemElement.click(); - return; - } - processWidgetPage.startProcess(name); - } - - public String getProcessResult(String name) { - ProcessWidgetPage processWidgetPage = getProcessWidget(); - if (processWidgetPage.isImageModeActivated()) { - WebElement processItem = processWidgetPage.getProcessItem(name); - WebElement processNameElement = findChildElementByCssSelector(processItem, ".js-process-start-list-item-name"); - return processNameElement.getText(); - } - return processWidgetPage.getProcess(name).getText(); - } - - public String getTaskResult(int index) { - TaskWidgetPage taskWidgetPage = new TaskWidgetPage("search-results-tabview:task-results") { - @Override - protected String getLoadedLocator() { - return "//*[contains(@id,'task-results:task-view')]"; - } - }; - return taskWidgetPage.getNameOfTaskAt(index); - } - - public String getCaseResult(int index) { - CaseWidgetPage caseWidgetPage = getCaseWidget(); - return caseWidgetPage.getCaseNameAt(index); - } - - public int countCase() { - CaseWidgetPage caseWidgetPage = getCaseWidget(); - return caseWidgetPage.getNumberOfCases(); - } - - private CaseWidgetPage getCaseWidget() { - return new CaseWidgetPage("search-results-tabview:case-results"); - } - - public boolean isCaseResultEmpty() { - CaseWidgetPage caseWidgetPage = getCaseWidget(); - return caseWidgetPage.isEmpty(); - } - - public boolean isProcessGroupDisplay(String group) { - ProcessWidgetPage processWidgetPage = getProcessWidget(); - return processWidgetPage.isProcessGroupDisplay(group); - } - - private ProcessWidgetPage getProcessWidget() { - return new ProcessWidgetPage("search-results-tabview:process-results"); - } - - public boolean isInfoWorkflowIcon() { - ProcessWidgetPage processWidget = getProcessWidget(); - if (processWidget.isImageModeActivated()) { - WebElement expressWorkflow = findElementByClassName("express-workflow"); - WebElement icon = findChildElementByClassName(expressWorkflow, "process-image-view-icon"); - return icon.getAttribute("class").contains("si si si-startup-launch"); - } - - WebElement element = findElementByCssSelector(INFO_EXPRESS_WORKFlOW); - return element.getAttribute("class").contains("si-information-circle"); - } - - public boolean isEditExpressWorkflow(String processName) { - ProcessWidgetPage processWidget = getProcessWidget(); - if (processWidget.isImageModeActivated()) { - WebElement actionMenu = getImageProcessActionMenuPanel(processName); - WebElement icon = findChildElementByCssSelector(actionMenu, "a[id$=':image-process-action-component:edit-process']"); - return icon != null; - } - WebElement element = findElementByCssSelector(EDIT_EXPRESS_WORKFlOW); - return element.getAttribute("class").contains("si-graphic-tablet-drawing-pen"); - } - - private WebElement getImageProcessActionMenuPanel(String processName) { - var selectedProcess = findListElementsByCssSelector("span.process-image-view-name").stream() - .filter(process -> processName.equalsIgnoreCase(process.getText())) - .findFirst().orElse(null); - var processActionMenuId = selectedProcess.getAttribute(ID_PROPERTY).replace("process-item-name", ""); - processActionMenuId = processActionMenuId.concat("process-item:image-process-action-component:process-action-menu"); - return findElementByCssSelector(String.format("div[id$='%s']", processActionMenuId)); - } - - public boolean isDeleteExpressWorkflown(String processName) { - ProcessWidgetPage processWidget = getProcessWidget(); - if (processWidget.isImageModeActivated()) { - WebElement actionMenu = getImageProcessActionMenuPanel(processName); - WebElement icon = findChildElementByCssSelector(actionMenu, "a[id$=':image-process-action-component:delete-process']"); - return icon != null; - } - WebElement element = findElementByCssSelector(DELETE_EXPRESS_WORKFlOW); - return element.getAttribute("class").contains("si-bin-1"); - } - - public boolean isExpressProcessLogo() { - ProcessWidgetPage processWidget = getProcessWidget(); - if (processWidget.isImageModeActivated()) { - return isInfoWorkflowIcon(); - } - WebElement element = findElementByCssSelector(EXPRESS_PROCESS_LOGO); - return element.getAttribute("class").contains("si-startup-launch"); - } - - public boolean isTaskCategoryColumnDisplayed() { - return findElementByCssSelector("span[id$=':task-category-cell']").isDisplayed(); - } - - public boolean isCaseCategoryColumnDisplayed() { - return findElementByCssSelector("span[id$=':case-category-cell']").isDisplayed(); - } - - public void waitForFirstTabFinishedLoading() { - waitForElementDisplayed(By.className("js-loading-process-list"), false); - waitForElementDisplayed(By.className("js-process-start-list-container"), true); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SecurityMemberNameAndAvatarComponentPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SecurityMemberNameAndAvatarComponentPage.java deleted file mode 100644 index 918496f6fc6..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/SecurityMemberNameAndAvatarComponentPage.java +++ /dev/null @@ -1,24 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class SecurityMemberNameAndAvatarComponentPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('content-container')"; - } - - public WebElement getCurrentSessionUserSecurityMemberNameAndAvatarComponentContainer() { - switchToIFrameOfTask(); - waitForElementDisplayed(By.id("current-session-user-security-member-name-and-avatar-component-container"), true); - return findElementById("current-session-user-security-member-name-and-avatar-component-container"); - } - - public WebElement getCurrentSessionRoleSecurityMemberNameAndAvatarComponentContainer() { - switchToIFrameOfTask(); - waitForElementDisplayed(By.id("current-session-role-security-member-name-and-avatar-component-container"), true); - return findElementById("current-session-role-security-member-name-and-avatar-component-container"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/StatisticWidgetPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/StatisticWidgetPage.java deleted file mode 100644 index 981e85cae99..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/StatisticWidgetPage.java +++ /dev/null @@ -1,291 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class StatisticWidgetPage extends TemplatePage { - public static final String TASK_BY_PRIORITY_CHART_NAME = "Task by priority chart"; - public static final String CASE_BY_STATE_CHART_NAME = "Case by state chart"; - public static final String TASK_BY_EXPIRY_CHART_NAME = "Task by expiry chart"; - public static final String ELAPSED_TIME_CHART_NAME = "Elapsed time chart"; - public static final String CASE_BY_FINISHED_TASK_CHART_NAME = "Case by finished task chart"; - public static final String CASE_BY_FINISHED_TIME_CHART_NAME = "Case by finished time chart"; - public static final String CASES_BY_CATEGORY_CHART_NAME = "Cases by category chart"; - - public StatisticWidgetPage() { - Sleeper.sleep(1000); - waitForPageLoaded(); - waitForElementDisplayed(By.id("statistics-widget"), true); - } - - @Override - protected String getLoadedLocator() { - return "id('statistics-widget')"; - } - - - @Override - protected long getTimeOutForLocator() { - return 30L; - } - - public void switchCreateMode() { - clickByCssSelector("a[id$='create-chart-link']"); - waitForElementDisplayed(By.cssSelector("a[id$='statistics-widget:back-from-chart-creation']"), true); - } - - public void backToDashboard() { - clickByCssSelector("a[id$='back-from-chart-creation']"); - waitForElementDisplayed(By.cssSelector("a[id$='create-chart-link']"), true); - } - - public TaskAnalysisWidgetPage navigateToTaskAnalysisPage() { - String taskAnalysisLinkString = "statistics-widget:task-analysis-page-navigation-link"; - waitForElementDisplayed(By.id(taskAnalysisLinkString), true, DEFAULT_TIMEOUT); - WebElement taskAnalysisLink = findElementById(taskAnalysisLinkString); - - taskAnalysisLink.click(); - waitForElementDisplayed(By.id("task-widget"), true, DEFAULT_TIMEOUT); - WaitHelper.assertTrueWithWait(() -> { - return isElementPresent(By.cssSelector(".js-layout-wrapper.has-breadcrumb")); - }); - - return new TaskAnalysisWidgetPage(); - } - - private boolean isCompactMode() { - waitForPageLoaded(); - waitForElementDisplayed(By.id("statistics-widget:widget-container"), true, DEFAULT_TIMEOUT); - WebElement statisticContainer = findElementById("statistics-widget:widget-container"); - return statisticContainer.getAttribute(CLASS_PROPERTY).contains("compact-mode"); - } - - public boolean isFullMode() { - return !isCompactMode(); - } - public boolean hasCreateChartsLink(){ - return isElementPresent(By.id("statistics-widget:create-chart-link-label")); - } - - public String getChartName(int chartIndex) { - Awaitility.await().atMost(new Duration(10, TimeUnit.SECONDS)).until(() -> { - try { - return findElementByCssSelector(String.format("div[id$='%d:chart-name-container'] .chart-name", chartIndex)).getText().length()>1; - } catch (WebDriverException e) { - System.out.println("Exception when waiting for element existed, try again."); - } - return false; - }); - WebElement chartName = findElementByCssSelector(String.format("div[id$='%d:chart-name-container'] .chart-name", chartIndex)); - return chartName.getText(); - } - - public Set getAllChartNames() { - return findListElementsByCssSelector("div[id$=':chart-name-container'] .chart-name").stream().map(e -> e.getText()) - .collect(Collectors.toSet()); - } - - public String getRestoreDefaultButtonName() { - return findElementByCssSelector("span[id$='restore-default-chart-link-label']").getText(); - } - - @SuppressWarnings("deprecation") - public void restoreDefaultCharts() { - Awaitility.await().atMost(new Duration(10, TimeUnit.SECONDS)).until(() -> { - WebElement restoreDefault = findElementByCssSelector("span[id$='restore-default-chart-link-label']"); - try { - return restoreDefault.getText().contains("Restore default"); - } catch (WebDriverException e) { - System.out.println("Exception when waiting for element existed, try again."); - } - return false; - }); - clickByCssSelector("span[id$='restore-default-chart-link-label']"); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.id("statistics-widget:restore-confirmation-dialog"), true, 30); - WebElement okButton = findElementById("statistics-widget:confirm-restore"); - click(okButton); - waitAjaxIndicatorDisappear(); - } - - private void inputNameForSupportedLanguages(String value) { - for (int i = 0; i < 4; i++) { - findElementByCssSelector("input[id$='" + i + ":chart-name-input']").sendKeys(value); - } - } - - @SuppressWarnings("deprecation") - public void createTaskByPriorityChart() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-task-by-priority-link"), true, 30); - click(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-task-by-priority-link")); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - inputNameForSupportedLanguages(TASK_BY_PRIORITY_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - waitAjaxIndicatorDisappear(); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void createTaskByPriorityChartMultiLanguage() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-task-by-priority-link"), true, 30); - click(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-task-by-priority-link")); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - - findElementByCssSelector("input[id$='0:chart-name-input']").sendKeys(TASK_BY_PRIORITY_CHART_NAME.concat(" English")); - findElementByCssSelector("input[id$='1:chart-name-input']").sendKeys(TASK_BY_PRIORITY_CHART_NAME.concat(" French")); - findElementByCssSelector("input[id$='2:chart-name-input']").sendKeys(TASK_BY_PRIORITY_CHART_NAME.concat(" German")); - findElementByCssSelector("input[id$='3:chart-name-input']").sendKeys(TASK_BY_PRIORITY_CHART_NAME.concat(" Spanish")); - - clickByCssSelector("button[id$='chart-save-command']"); - waitAjaxIndicatorDisappear(); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - - @SuppressWarnings("deprecation") - public void createCaseByStateChart() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-case-by-state-link"), true, 30); - WebElement createCaseByStateLink - = findElementById("statistics-widget:chart-creation-widget:chart-management-form:create-case-by-state-link"); - click(createCaseByStateLink); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - - inputNameForSupportedLanguages(CASE_BY_STATE_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - - waitAjaxIndicatorDisappear(); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void createTaskByExpiryChart() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-task-by-expiry-link"), true, 30); - WebElement createTaskByExpiryLink - = findElementById("statistics-widget:chart-creation-widget:chart-management-form:create-task-by-expiry-link"); - click(createTaskByExpiryLink); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - inputNameForSupportedLanguages(TASK_BY_EXPIRY_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - - waitAjaxIndicatorDisappear(); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void createElapsedTimeChart() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-elapsed-time-link"), true, 30); - WebElement createElapsedTimeLink - = findElementById("statistics-widget:chart-creation-widget:chart-management-form:create-elapsed-time-link"); - click(createElapsedTimeLink); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - inputNameForSupportedLanguages(ELAPSED_TIME_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - - waitAjaxIndicatorDisappear(); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - public void createCaseByFinishedTask() { - var caseByFinishedTaskSelector = "button[id$=':chart-management-form:create-case-by-finished-task-link']"; - waitForElementDisplayed(By.cssSelector(caseByFinishedTaskSelector), true); - clickByCssSelector(caseByFinishedTaskSelector); - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, - "statistics-widget\\:chart-creation-widget\\:add-statistic-form\\:chart-name-list\\:0\\:chart-name-input", - CLASS_PROPERTY); - - inputNameForSupportedLanguages(CASE_BY_FINISHED_TASK_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), false); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void createCaseByFinishTime() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-case-by-finished-time-link"), true, 30); - WebElement createCaseByFinishedTaskLink - = findElementById("statistics-widget:chart-creation-widget:chart-management-form:create-case-by-finished-time-link"); - click(createCaseByFinishedTaskLink); - waitAjaxIndicatorDisappear(); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - inputNameForSupportedLanguages(CASE_BY_FINISHED_TIME_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - - waitAjaxIndicatorDisappear(); - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - public void createCasesByCategory() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-cases-by-category-link"), true, 30); - WebElement createCaseByFinishedTaskLink - = findElementById("statistics-widget:chart-creation-widget:chart-management-form:create-cases-by-category-link"); - click(createCaseByFinishedTaskLink); - - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - inputNameForSupportedLanguages(CASES_BY_CATEGORY_CHART_NAME); - clickByCssSelector("button[id$='chart-save-command']"); - - waitForElementExisted("span[class='ui-growl-title']", true, DEFAULT_TIMEOUT); - } - - public WebElement getChartCreationContainer() { - return findElementById("statistics-widget:chart-creation-widget:chart-management-form:chart-list"); - } - - @SuppressWarnings("deprecation") - public WebElement getCaseByFinishedTaskCreationDialog() { - waitForElementDisplayed(By.id("statistics-widget:chart-creation-widget:chart-management-form:create-case-by-finished-task-link"), true, 30); - WebElement createCaseByFinishedTaskLink - = findElementById("statistics-widget:chart-creation-widget:chart-management-form:create-case-by-finished-task-link"); - click(createCaseByFinishedTaskLink); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.cssSelector("div[id$='add-chart-dialog']"), true); - inputNameForSupportedLanguages(CASE_BY_FINISHED_TASK_CHART_NAME); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "statistics-widget\\\\:chart-creation-widget\\\\:add-statistic-form\\\\:chart-name-list\\\\:3\\\\:chart-name-input", "id"); - return findElementByCssSelector("div[id$='add-chart-dialog']"); - } - - public void waitForChartCreationPageRendered() { - waitForElementDisplayed(By.id("statistics-widget:back-from-chart-creation"), true); - } - - @SuppressWarnings("deprecation") - public void waitForAllChartLoaded() { - ensureNoBackgroundRequest(); - Sleeper.sleep(5000);//wait for last chart animation finish - } - - public WebElement getChartPanelByIndex(int index) { - return findElementByCssSelector(String.format("span[id$='%d:chart-panel']", index)); - } - - public WebElement getChartInfoDialogOfChart(int chartIndex) { - List chartInfoIcons = findListElementsByClassName("chart-info"); - click(chartInfoIcons.get(chartIndex)); - waitForElementDisplayed(By.id("statistics-widget:statistic-dashboard-widget:chart-details-dialog"), true); - return findElementById("statistics-widget:statistic-dashboard-widget:chart-details-dialog"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskAnalysisWidgetPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskAnalysisWidgetPage.java deleted file mode 100644 index 949c1e49a78..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskAnalysisWidgetPage.java +++ /dev/null @@ -1,378 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - - -public class TaskAnalysisWidgetPage extends TemplatePage { - - private static final String TASK_FILTER_SELECTION = "task-widget:task-filter-add-form:task-filter-selection"; - private static final String WIDGET_ID = "task-widget"; - - public TaskAnalysisWidgetPage() { - } - - @Override - protected String getLoadedLocator() { - return "//*[contains(@id,'" + WIDGET_ID + ":statistic-result-list')]"; - } - - public StatisticWidgetPage navigateToStatisticPage() { - String backButtonId = "task-widget:back-button"; - waitForElementDisplayed(By.id(backButtonId), true, DEFAULT_TIMEOUT); - WebElement backButton = findElementById(backButtonId); - - click(backButton); - waitForElementDisplayed(By.id("statistics-widget"), true, DEFAULT_TIMEOUT); - return new StatisticWidgetPage(); - } - - public WebElement findColumnToggler() { - String togglerId = "task-widget:statistic-result-form:toggler"; - waitForElementDisplayed(By.id(togglerId), true); - return findElementById(togglerId); - } - - private WebElement findTaskFilterButton() { - String taskFilterButtonId = "task-widget:task-filter-add-action"; - waitForElementDisplayed(By.id(taskFilterButtonId), true); - return findElementById(taskFilterButtonId); - } - - private WebElement findCaseFilterButton() { - String caseFilterButtonId = "task-widget:case-filter-add-action"; - waitForElementDisplayed(By.id(caseFilterButtonId), true); - return findElementById(caseFilterButtonId); - } - - public WebElement findApplyFilterButton() { - String applyFilterButtonId = "task-widget:apply-filter"; - waitForElementDisplayed(By.id(applyFilterButtonId), true); - return findElementById(applyFilterButtonId); - } - - @SuppressWarnings("deprecation") - public void openAdvancedTaskFilter(String filterName, String filterIdName) { - click(findTaskFilterButton()); - waitForElementDisplayed(By.id(TASK_FILTER_SELECTION), true); - WebElement filterSelectionElement = findElementById(TASK_FILTER_SELECTION); - for (WebElement filterElement : findChildElementsByTagName(filterSelectionElement, "LABEL")) { - if (filterName.equals(filterElement.getText())) { - click(filterElement); - click(By.cssSelector("button[id$='task-widget:task-filter-add-form:update-task-filter-selected-command']")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - break; - } - } - waitForElementDisplayed( - By.cssSelector("span[id$='" + filterIdName + "-filter:filter-open-form:advanced-filter-item-container']"), true); - } - - @SuppressWarnings("deprecation") - public void openAdvancedCaseFilter(String filterName, String filterIdName) { - click(findCaseFilterButton()); - waitForElementDisplayed(findElementById("task-widget:case-filter-add-form:case-filter-selection"), true); - WebElement filterSelectionElement = findElementById("task-widget:case-filter-add-form:case-filter-selection"); - for (WebElement filterElement : findChildElementsByTagName(filterSelectionElement, "LABEL")) { - if (filterName.equals(filterElement.getText())) { - click(filterElement); - click(By.cssSelector("button[id$='task-widget:case-filter-add-form:update-task-filter-selected-command']")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - break; - } - } - waitForElementDisplayed( - By.cssSelector("span[id$='" + filterIdName + "-filter:filter-open-form:advanced-filter-item-container']"), true); - } - - @SuppressWarnings("deprecation") - public void filterByTaskName(String text) { - click(By.cssSelector("[id$='task-name-filter:filter-open-form:advanced-filter-command']")); - WebElement nameInput = - findElementByCssSelector("input[id$='task-name-filter:filter-input-form:name']"); - waitForElementReallyDisplayed(nameInput, true); - enterKeys(nameInput, text); - click(By.cssSelector("[id$='task-name-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByTaskPriority(List selectedPriorities) { - click(By.cssSelector("[id$='priority-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("[id$='priority-filter:filter-input-form:advanced-filter-panel-content']"), true); - WebElement selectionElement = findElementByCssSelector("[id$='priority-filter:filter-input-form:advanced-filter-panel-content']"); - for (WebElement labelElement : findChildElementsByTagName(selectionElement, "LABEL")) { - if (!selectedPriorities.contains(labelElement.getText())) { - click(labelElement); - } - } - click(By.cssSelector("[id$='priority-filter:filter-input-form:update-command']")); - waitForPageLoaded(); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByTaskCategory(String selectedCategory) { - click(By.cssSelector("[id$='task-category-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("div[id$=':task-category-filter-tree']"), true); - WebElement selectionElement = findElementByCssSelector("[id$='task-category-filter:filter-input-form:advanced-filter-panel-content']"); - List categoryTreeLabels = findChildElementsByClassName(selectionElement, "ui-treenode-label"); - //Find parent node of tree first and uncheck it - WebElement parentNodeOfTree = categoryTreeLabels.stream().findFirst().get(); - waitForElementDisplayed(parentNodeOfTree, true); - click(parentNodeOfTree); - for (WebElement labelElement : categoryTreeLabels) { - if (selectedCategory.contains(labelElement.getText())) { - click(labelElement); - break; - } - } - click(By.cssSelector("[id$='task-category-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByCaseName(String text) { - click(By.cssSelector("[id$='case-name-filter:filter-open-form:advanced-filter-command']")); - WebElement nameInput = - findElementByCssSelector("input[id$='case-name-filter:filter-input-form:name']"); - enterKeys(nameInput, text); - click(By.cssSelector("[id$='case-name-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByCaseState(List selectedPriorities) { - click(By.cssSelector("div[id$='task-widget:case-filters-container'] button[id$='state-filter:filter-open-form:advanced-filter-command']")); - WebElement selectionElement = findElementByCssSelector("div[id$='task-widget:case-filters-container'] div[id$='state-filter:filter-input-form:advanced-filter-panel-content']"); - for (WebElement labelElement : findChildElementsByTagName(selectionElement, "LABEL")) { - if (!selectedPriorities.contains(labelElement.getText())) { - click(labelElement); - waitAjaxIndicatorDisappear(); - } - } - click(By.cssSelector("div[id$='task-widget:case-filters-container'] button[id$='state-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByCaseCategory(String selectedCategory) { - click(By.cssSelector("[id$='case-category-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("div[id$=':case-category-filter-tree']"), true); - WebElement selectionElement = findElementByCssSelector("[id$='case-category-filter:filter-input-form:advanced-filter-panel-content']"); - List categoryTreeLabels = findChildElementsByClassName(selectionElement, "ui-treenode-label"); - //Find parent node of tree first and uncheck it - WebElement parentNodeOfTree = categoryTreeLabels.stream().findFirst().get(); - waitForElementDisplayed(parentNodeOfTree, true); - click(parentNodeOfTree); - for (WebElement labelElement : categoryTreeLabels) { - if (selectedCategory.contains(labelElement.getText())) { - click(labelElement); - break; - } - } - click(By.cssSelector("button[id$='case-category-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void saveFilterSet(String filterSetName, boolean isPersonalFilter) { - enterDataToSaveFilterSet(filterSetName, isPersonalFilter); - - click(By.id("task-widget:filter-save-form:filter-save-command")); - waitAjaxIndicatorDisappear(); - } - - public void enterDataToSaveFilterSet(String filterSetName, boolean isPersonalFilter) { - click(By.id("task-widget:filter-save-action")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - waitForElementDisplayed(By.id("task-widget:filter-save-form:save-filter-set-name-input"), true); - enterKeys(findElementById("task-widget:filter-save-form:save-filter-set-name-input"), filterSetName); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "save-filter-set-dialog .ui-inputtext", "class"); - - WebElement filterVisibilityContainer = findElementById("task-widget:filter-save-form:save-filter-type-radio"); - if (isPersonalFilter) { - click(filterVisibilityContainer.findElements(By.tagName("LABEL")).get(0)); - } else { - click(filterVisibilityContainer.findElements(By.tagName("LABEL")).get(1)); - } - } - - @SuppressWarnings("deprecation") - public void loadFilterSet(String filterSetName, boolean isPersonalFilter) { - waitForElementDisplayed(By.id("task-widget:filter-selection-form:filter-name"), true); - click(By.id("task-widget:filter-selection-form:filter-name")); - waitForElementDisplayed(findElementById("task-widget:filter-selection-form:filter-name-overlay-panel"), true); - WebElement filterContainer = null; - if (isPersonalFilter) { - filterContainer = findElementById("task-widget:filter-selection-form:private-filters"); - } else { - filterContainer = findElementById("task-widget:filter-selection-form:public-filters"); - } - click(filterContainer.findElement(By.linkText(filterSetName))); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - public String getFilterName() { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until( - () -> findElementByCssSelector("a[id$='task-widget:filter-selection-form:filter-name'] > span:nth-child(2)") - .getText().length()>1); - WebElement filterName = findElementByCssSelector("a[id$='task-widget:filter-selection-form:filter-name'] > span:nth-child(2)"); - return filterName.getText(); - } - - public boolean isResetButtonShown() { - waitForElementDisplayed(By.cssSelector("[id$='task-widget:filter-reset-action']"), true); - return isElementDisplayed(By.cssSelector("[id$='task-widget:filter-reset-action']")); - } - - @SuppressWarnings("deprecation") - public void resetFilter() { - click(By.cssSelector("[id$='task-widget:filter-reset-action']")); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.cssSelector("[id$='task-widget:filter-reset-command']"), true); - click(By.cssSelector("[id$='task-widget:filter-reset-command']")); - waitAjaxIndicatorDisappear(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until( - () -> findElementByCssSelector("a[id$='task-widget:filter-selection-form:filter-name'] > span:nth-child(2)") - .getText().contains("Default")); - } - - public void filterUserInCase(String user, String filterName,String filterIdName) { - openAdvancedCaseFilter(filterName, filterIdName); - filterByUserName(user, filterIdName); - } - - @SuppressWarnings("deprecation") - private void filterByUserName(String user, String filterIdName) { - click(By.cssSelector("button[id$='"+filterIdName+"-filter:filter-open-form:advanced-filter-command']")); - WebElement responsible = findElementByCssSelector("input[id*='"+filterIdName+"-filter:filter-input-form:']"); - type(responsible, user); - waitAjaxIndicatorDisappear(); - waitForElementExisted("div[id*='" + filterIdName + "-filter'] .ui-avatar-text", true, 5); - click(By.cssSelector("tr[class$='ui-state-highlight']")); - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='"+filterIdName+"-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void removeUserInFilter() { - waitForElementDisplayed(By.cssSelector("button[id$='creator-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='creator-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']"), - true); - findElementByCssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']").click(); - findElementByCssSelector("input[id$='creator-filter:filter-input-form:creator-component:creator-select_input']").clear(); - click(By.cssSelector("button[id$='creator-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void removeResponsible() { - waitForElementDisplayed(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']"), - true); - findElementByCssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']").click(); - findElementByCssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']").clear(); - click(By.cssSelector("button[id$='responsible-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByResponsible(String user, String filterName,String filterIdName) { - openAdvancedTaskFilter(filterName, filterIdName); - click(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']")); - WebElement responsible = - findElementByCssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']"); - //enterKeys(responsible, text); - type(responsible,user); - waitForElementDisplayedByCssSelector("span[id$='responsible-filter:filter-input-form:responsible_panel']"); - waitForElementDisplayedByCssSelector("div[id*='responsible-filter'] .ui-avatar-text", 5); - click(By.cssSelector("div[id*='responsible-filter'] .ui-avatar-text")); - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='responsible-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByOwner(String user) { - openAdvancedCaseFilter("Owner", "owner"); - click(By.cssSelector("button[id$='owner-filter:filter-open-form:advanced-filter-command']")); - WebElement owner = - findElementByCssSelector("input[id$='owner-filter:filter-input-form:owner_input']"); - type(owner, user); - waitForElementDisplayedByCssSelector("span[id$='owner-filter:filter-input-form:owner_panel']"); - waitForElementDisplayedByCssSelector("div[id*='owner-filter'] .ui-avatar-text", 5); - click(By.cssSelector("div[id*='owner-filter'] .ui-avatar-text")); - click(By.cssSelector("button[id$='owner-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - public String getUser(String filterName) { - waitForElementDisplayed(By.cssSelector("button[id$='" + filterName + "-filter:filter-open-form:advanced-filter-command']"),true,DEFAULT_TIMEOUT); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector( - "button[id$='" + filterName + "-filter:filter-open-form:advanced-filter-command'] > span").getText() - .length() > 1); - return findElementByCssSelector( - "button[id$='" + filterName + "-filter:filter-open-form:advanced-filter-command'] > span").getText(); - } - - public List getRowsInTaskTable() { - return findElementById("task-widget:statistic-result-form:task-table_data").findElements(By.cssSelector("tr[role='row']")); - } - - @SuppressWarnings("deprecation") - public void clickApplyFilter() { - click(By.cssSelector("button[id$='task-widget:apply-filter']")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - public void waitForTaskDataChangeToSpecificSize(int size) { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> { - return getRowsInTaskTable().size() == size; - }); - } - - public WebElement getSavingFilterDialog() { - return findElementByCssSelector("div[id$='save-filter-set-dialog']"); - } - - public void openNoActivatorFilter(String filterName) { - findTaskFilterButton().click(); - WebElement filterSelectionElement = findElementById(TASK_FILTER_SELECTION); - for (WebElement filterElement : findChildElementsByTagName(filterSelectionElement, "LABEL")) { - if (filterName.equals(filterElement.getText())) { - filterElement.click(); - click(By.cssSelector("button[id$='task-widget:task-filter-add-form:update-task-filter-selected-command']")); - break; - } - } - } - - public void filterByUnavailableActivator() { - waitForElementDisplayed(By.cssSelector("button[id$='available-activator-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='available-activator-filter:filter-open-form:advanced-filter-command']")); - - waitForElementDisplayed(By.cssSelector("[id$='available-activator-filter:filter-input-form:available-activator']"), - true); - WebElement displayOnlyUnavailableTaskCheckbox = findElementByCssSelector("[id$='available-activator-filter:filter-input-form:available-activator']"); - displayOnlyUnavailableTaskCheckbox.click(); - click(By.cssSelector("button[id$='available-activator-filter:filter-input-form:update-command']")); - } -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskDetailsPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskDetailsPage.java deleted file mode 100644 index 8cca3f40175..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskDetailsPage.java +++ /dev/null @@ -1,489 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.Action; -import org.openqa.selenium.interactions.Actions; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.Sleeper; -import portal.guitest.common.TaskState; -import portal.guitest.common.WaitHelper; - -public class TaskDetailsPage extends TemplatePage { - - private static final String UI_INPLACE_SAVE = "ui-inplace-save"; - - @Override - protected String getLoadedLocator() { - return "id('task-detail-template:task-detail-container')"; - } - - public TaskDetailsPage() {} - - public String getCreatedOnDateText() { - return findElementByCssSelector("span[id$='start-date']").getText(); - } - - public String getDurationTimeText() { - return findElementByCssSelector("span[id$='duration-time']").getText(); - } - - public List getTaskNoteAuthors() { - List noteAuthorElements = findListElementsByCssSelector("td.task-document-author .name-after-avatar"); - return noteAuthorElements.stream().map(w -> w.getText()).collect(Collectors.toList()); - } - - public void changePriorityOfTask(int priorityValue) { - findElementByCssSelector("[id$=':general-information:priority-form:edit-priority-inplace_display']").click(); - waitForElementDisplayed(By.cssSelector("[id$=':general-information:priority-form:priority-select-menu_label']"), - true); - findElementByCssSelector("[id$=':general-information:priority-form:priority-select-menu_label']").click(); - WebElement prioritySelectElement = findElementByCssSelector( - String.format("[id$=':general-information:priority-form:priority-select-menu_%d']", priorityValue)); - waitForElementDisplayed(prioritySelectElement, true); - prioritySelectElement.click(); - clickByCssSelector( - "[id$=':general-information:priority-form:edit-priority-inplace_editor'] .ui-inplace-save"); - waitForElementDisplayed(By.cssSelector("[id$=':general-information:priority-form:edit-priority-inplace_editor'] .ui-inplace-save"), false); - } - - public String getPriorityOfTask() { - return findElementByCssSelector("span[id$='edit-priority-inplace_display']").getText(); - } - - @SuppressWarnings("deprecation") - public void changeNameOfTask(String name) { - clickByCssSelector("span[id$='task-name-inplace_display']"); - WebElement taskNameInput = findElementByCssSelector("input[id$='task-name-input']"); - waitForElementDisplayed(taskNameInput, true); - taskNameInput.clear(); - taskNameInput.sendKeys(name); - clickByCssSelector( - "#:task-detail-title-form\\:task-name-inplace_editor .ui-inplace-save"); - waitAjaxIndicatorDisappear(); - } - - - public String getNameOfTaskWhenDisplayingDetailsAt() { - return findElementByCssSelector("span[id$='task-name-inplace_display']").getText(); - } - - public boolean isAddNoteButtonDisplayed() { - return isElementDisplayed(By.cssSelector("[id$=':task-notes:add-note-command']")); - } - - public boolean isShowMoreNoteButtonDisplayed() { - return isElementDisplayed(By.cssSelector("[id$=':task-notes:show-more-note-link']")); - } - - public boolean isAddDocumentLinkDisplayed() { - return isElementDisplayed(By.cssSelector("[id$=':task-documents:add-document-command']")); - } - - public TaskWidgetPage goBackToTaskListFromTaskDetails() { - clickBackButton(); - return new TaskWidgetPage(); - } - - public boolean isBackButtonPresented() { - return findElementByCssSelector("[id$=':task-detail-title-form:back-to-previous-page']").isDisplayed(); - } - - public void clickBackButton() { - click(By.cssSelector("[id$=':task-detail-title-form:back-to-previous-page']")); - } - - public TaskTemplatePage clickStartTask() { - findElementByCssSelector("[id$=':task-detail-start-command']").click(); - return new TaskTemplatePage(); - } - - @SuppressWarnings("deprecation") - public void clickTaskListBreadCrumb() { - click(By.cssSelector(".portal-breadcrumb ol li:nth-of-type(2) .ui-menuitem-link")); - ensureNoBackgroundRequest(); - } - - public String getTaskName() { - String[] breadcrumbTexts = getTextOfCurrentBreadcrumb().split(":"); - int item = breadcrumbTexts.length; - if (item > 1) { - return breadcrumbTexts[item - 1].trim(); - } - return breadcrumbTexts[0].trim(); - } - - public String getTaskNameInDialog() { - waitForElementDisplayed(By.cssSelector("span[id='task-detail-template:task-detail-title-form:task-name-edit-form']"), true); - return findElementByCssSelector("span[id='task-detail-template:task-detail-title-form:task-name-edit-form']").getText(); - } - - public CaseDetailsPage backToCaseDetails() { - clickBackButton(); - return new CaseDetailsPage(); - } - - - public WebElement getTaskGeneralInformation() { - return findElementByCssSelector("[id$=':task-detail-general-container']"); - } - - public void openAddNoteDialog() { - findElementByCssSelector("[id$=':task-notes:add-note-command']").click(); - waitForElementDisplayed(By.cssSelector("[id$=':task-notes:add-new-note-dialog']"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-inputfield.ui-inputtextarea.note-content-textarea", CLASS_PROPERTY); - } - - public WebElement getAddNoteDialog() { - return findElementByCssSelector("[id$=':task-notes:add-new-note-dialog']"); - } - - public void openAddAttachmentDialog() { - findElementByCssSelector("[id$=':task-documents:add-document-command']").click(); - waitForElementDisplayed(By.cssSelector("[id$=':task-documents:document-upload-dialog']"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-dialog.document-upload-dialog", CLASS_PROPERTY); - } - - @SuppressWarnings("deprecation") - public void addNoteToTaskWithContent(String content) { - waitForElementDisplayed(By.cssSelector("div.ui-dialog[aria-hidden='false']"), true); - WebElement addNoteDialog = findElementByCssSelector("div.ui-dialog[aria-hidden='false']"); - waitForElementDisplayed(addNoteDialog, true); - addNoteDialog.findElement(By.cssSelector("textarea[id$='note-content']")).sendKeys(content); - click(addNoteDialog.findElement(By.cssSelector("button[id$='save-add-note-command']"))); - waitAjaxIndicatorDisappear(); - } - - public void uploadDocument(String path) { - Sleeper.sleep(500); - uploadDocumentByPath(path); - waitForElementDisplayed(By.cssSelector("span[class$='ui-messages-info-summary']"), true); - click(By.cssSelector("button[id$=':task-documents:document-upload-close-command']")); - } - - private void uploadDocumentByPath(String path) { - findElementByCssSelector("input[id$='document-upload-panel_input']").sendKeys(path); - } - - public void waitUtilsTaskDetailsDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$=':task-detail-container']"), true); - } - - public WebElement getTaskHistories() { - return findElementByCssSelector("[id$=':task-detail-note-container']"); - } - - public WebElement getTaskAttachment() { - return findElementByCssSelector("[id$=':task-detail-document-container']"); - } - - public WebElement getSwitchToEditModeButtonElement() { - return findElementByCssSelector("[id$=':switch-to-edit-mode-button']"); - } - - public WebElement getSwitchToViewModeButtonElement() { - return findElementByCssSelector("[id$=':switch-to-view-mode-button']"); - } - - public WebElement getResetButtonElement() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-details-settings-button']"), true); - return findElementByCssSelector("[id$=':reset-details-settings-button']"); - } - - public WebElement getAddAttachmentDialog() { - return findElementByCssSelector("[id$=':task-documents:document-upload-dialog']"); - } - - public void clickOnDeleteDocumentIcon(int index) { - String deleteIconId = String.format("[id$=':task-documents:task-details-documents:%s:delete-file']", index); - findElementByCssSelector(deleteIconId).click(); - waitForElementDisplayed(By.cssSelector("[id$=':task-documents:document-deletion-dialog_content']"), true); - } - - public WebElement getDeleteDocumentConfirmDialog() { - return findElementByCssSelector("[id$=':task-documents:document-deletion-dialog']"); - } - - public void clickOnShowMoreHistories() { - findElementByCssSelector("[id$=':task-notes:show-more-note-link']").click(); - } - - public String getTaskResponsible() { - return findElementByCssSelector(".role-and-user-information .task-activator").getText(); - } - - public String getTaskId() { - return findElementByCssSelector("[id$=':task-id']").getText(); - } - - public String getFirstTaskNoteComment() { - return findElementByCssSelector("a[id$=':task-notes:task-note-table:0:note-message']").getText(); - } - - public void openTaskDelegateDialog() { - openActionPanel(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector("a[id$='\\:task-delegate-command']").isDisplayed()); - clickByCssSelector("a[id$='\\:task-delegate-command']"); - waitForElementDisplayed(By.cssSelector("div[id$='task-delegate-dialog']"), true); - } - - public void openActionPanel() { - waitForElementDisplayed(By.cssSelector("[id$=':additional-options:task-detail-more-step']"), true); - click(By.cssSelector("[id$=':additional-options:task-detail-more-step']")); - waitForElementDisplayed(By.cssSelector("[id$=':additional-options:side-steps-panel']"),true); - } - - public boolean isActionLinkEnable() { - return !findElementByClassName("action-link").getAttribute("class").contains("ui-state-disabled"); - } - - public List getActiveTaskAction() { - openActionPanel(); - WebElement actionPanel = findElementByCssSelector("div[id$=':additional-options:side-steps-panel']"); - return actionPanel.findElements(By.cssSelector("a[class*='option-item']")).stream().map(WebElement::getText).collect(Collectors.toList()); - } - - public void addCommentOnTaskDelegationDialog(String comment) { - waitForElementDisplayed(By.cssSelector("textarea[id$=':task-item-delegate-component:task-delegate-form:input-text-area-delegate-message']"), true); - type(By.cssSelector("textarea[id$=':task-item-delegate-component:task-delegate-form:input-text-area-delegate-message']"), comment); - } - - @SuppressWarnings("deprecation") - public void selectDelegateResponsible(String responsibleName, boolean isRole) { - if(isRole) { - List radioButtonLabels = findListElementsByCssSelector("table[id$='activator-type-select'] label"); - click(radioButtonLabels.get(1)); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.cssSelector("input[id$='group-activator-select_input']"), true); - type(By.cssSelector("input[id$='group-activator-select_input']"), responsibleName); - waitForElementDisplayed(By.cssSelector("span[id$='group-activator-select_panel']"), true); - List foundRoles = - findListElementsByCssSelector("span[id$='group-activator-select_panel'] .name-after-avatar"); - click(foundRoles.get(0)); - } - else { - waitForElementDisplayed(By.cssSelector("input[id$='user-activator-select_input']"), true); - type(By.cssSelector("input[id$='user-activator-select_input']"), responsibleName); - waitForElementDisplayed(By.cssSelector("span[id$='user-activator-select_panel']"), true); - List foundUsers = - findListElementsByCssSelector("span[id$='user-activator-select_panel'] .name-after-avatar"); - click(foundUsers.get(0)); - } - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='proceed-task-delegate-command']")); - waitForElementDisplayed(By.cssSelector("div[id$='task-delegate-dialog']"), false); - } - - public void changeExpiryOfTaskAt(String dateStringLiteral) { - click(By.cssSelector("[id$=':expiry-form:edit-inplace_display']")); - - waitForElementDisplayed(By.cssSelector("[id$=':expiry-form:expiry-calendar']"), true); - WebElement taskExpiryInlineEdit = findElementByCssSelector("[id$=':expiry-form:expiry-calendar_input']"); - taskExpiryInlineEdit.sendKeys(dateStringLiteral); - - WebElement editor = findElementByCssSelector("[id$=':expiry-form:edit-inplace_editor']"); - WebElement saveButton = findChildElementByClassName(editor, UI_INPLACE_SAVE); - - saveButton.click(); - waitForElementDisplayed(By.cssSelector("[id$=':expiry-form:edit-inplace_editor']"), false); - } - - public boolean isClearDelayTimeDisplayed() { - return isElementDisplayed(findElementByCssSelector("[id$=':additional-options:task-clear-delay-command']")); - } - - public boolean isDelayTimeDisplayed() { - try { - return isElementDisplayed(findElementByCssSelector("[id$=':delay-form:delay-date']")); - } catch (NoSuchElementException ex) { - return false; - } - } - - public void clickOnClearDelayTime() { - findElementByCssSelector("a[id$=':additional-options:task-clear-delay-command']").click(); - waitForElementDisplayed(By.cssSelector("[id$=':additional-options:side-steps-panel']"), false); - } - - public boolean isClearDeadlineDisplayed() { - return isElementDisplayed(findElementByCssSelector("[id$=':additional-options:task-clear-expiry-command']")); - } - - public void clickOnClearDeadlineTime() { - findElementByCssSelector("a[id$=':additional-options:task-clear-expiry-command']").click(); - waitForElementDisplayed(By.cssSelector("[id$=':additional-options:side-steps-panel']"), false); - } - - public String getTaskState() { - WebElement taskStateComponent = findElementByCssSelector("[id$=':general-information:task-detail-state']"); - String stateStyleClass = taskStateComponent.findElement(By.cssSelector("i[class*='task-state']")).getAttribute("class"); - return TaskState.fromClass(Stream.of(stateStyleClass.trim().split(" ")).filter(style -> style.endsWith("-task-state")).findFirst().orElse("")).name(); - } - - public String getTaskDelayTime() { - return findElementByCssSelector("span[id$='general-information:delay-form:delay-date_display']").getText(); - } - - public void updateDelayTimestamp(String tomorrow, String tomorrowWithLocale) { - findElementByCssSelector("span[id$='general-information:delay-form:delay-date_display']").click(); - waitForElementDisplayed(findElementByCssSelector("[id$='general-information:delay-form:delay-date-calendar_panel']"), true); - WebElement delayInput = findElementByCssSelector("[id$='delay-form:delay-date-calendar_input']"); - delayInput.sendKeys(Keys.chord(Keys.CONTROL, "a")); - delayInput.sendKeys(Keys.BACK_SPACE); - delayInput.sendKeys(tomorrow); - WebElement buttonAction = findElementByCssSelector("[id$='delay-form:delay-date_editor']"); - buttonAction.findElement(By.className("ui-inplace-save")).click(); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("span[id$=':delay-form:delay-date_display']").getText().equalsIgnoreCase(tomorrowWithLocale)); - } - - public boolean isShowWorkflowEventsLinkDisplayed() { - return isElementDisplayedById("form:show-workflow-event"); - } - - public String openWorkflowEventDialog() { - openActionPanel(); - clickOnShowWorkflowEventLink(); - return getDataOfWorkflowEventsTable(); - } - - private String getDataOfWorkflowEventsTable() { - WebElement eventTable = findElementByCssSelector("tbody[id$='events-table_data']"); - List cells = eventTable.findElements(By.cssSelector("td")); - return String.join(",", cells.stream().map(WebElement::getText).collect(Collectors.toList())); - } - - public void clickOnShowWorkflowEventLink() { - findElementByCssSelector("a[id$=':task-workflow-event-command']").click(); - waitForElementDisplayed(By.cssSelector("div[id$='events-table']"), true); - } - - public WebElement getWorkflowEventsTable() { - waitForElementDisplayed(By.cssSelector("th[id*='events-table:']"), true); - return findElementByCssSelector("div[id$='workflow-events-dialog']"); - } - - public String getExpiryOfTaskAt() { - waitForElementDisplayed(By.cssSelector("[id$=':expiry-form:edit-inplace_display']"), true); - WebElement taskExpiry = findElementByCssSelector("[id$=':expiry-form:edit-inplace_display']"); - return taskExpiry.getText(); - } - - public void clickOnResetToDefaultButton() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-details-settings-button']"), true); - click(By.cssSelector("[id$=':reset-details-settings-button']")); - } - - public void clickOnSwitchToEditModeButton() { - waitForElementDisplayed(By.cssSelector("[id$=':switch-to-edit-mode-button']"), true); - click(By.cssSelector("[id$=':switch-to-edit-mode-button']")); - WaitHelper.assertTrueWithWait(() -> { - var infoWidget = findElementByCssSelector("[id$='task-details-information-panel']"); - return infoWidget.getAttribute(CLASS_PROPERTY).contains("ui-resizable ui-resizable-autohide"); - }); - } - - public void waitForSwitchToViewModeButtonDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$=':switch-to-view-mode-button']"), true); - } - - public void clickOnSwitchToViewModeButton() { - waitForElementDisplayed(By.cssSelector("[id$=':switch-to-view-mode-button']"), true); - click(By.cssSelector("[id$=':switch-to-view-mode-button']")); - } - - public void drapAndDropWidgets(String sourceName, String destinationName) { - waitForElementDisplayed(By.cssSelector(String.format("[id$=':task-detail-%s-container']", sourceName)), true); - WebElement sourceElement = findElementByCssSelector(String.format("[id$=':task-detail-%s-container']", sourceName)); - waitForElementDisplayed(By.cssSelector(String.format("[id$=':task-detail-%s-container']", destinationName)), true); - WebElement destinationElement = findElementByCssSelector(String.format("[id$=':task-detail-%s-container']", destinationName)); - Actions actions = new Actions(driver); - Action moveWidget = actions.dragAndDrop(sourceElement, destinationElement).build(); - moveWidget.perform(); - WaitHelper.assertTrueWithWait(() -> { - var taskDetails = findElementByCssSelector("[id$='task-detail-template:task-details-widgets']"); - return !taskDetails.getAttribute(CLASS_PROPERTY).contains("ui-droppable-over"); - }); - } - - public void waitForResetButtonDisplayed() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-details-settings-button']"), true); - } - - public void changeEscaltionActivatorTo(String activatorName, boolean isUser) { - boolean canEditExpiryActivator = canChangeEscalationActivator(); - if (canEditExpiryActivator) { - clickOnEditEscaltionEditIcon(); - if (isUser) { - waitForElementDisplayed(By.cssSelector("input[id$=':user-expiry-activator-select_input']"), true); - type(By.cssSelector("input[id$=':user-expiry-activator-select_input']"), activatorName); - waitForElementDisplayed(By.cssSelector("span[id$=':user-expiry-activator-select_panel']"), true); - List foundUsers = - findListElementsByCssSelector("span[id$=':user-expiry-activator-select_panel'] .name-after-avatar"); - click(foundUsers.get(0)); - } else { - List radioButtonLabels = findListElementsByCssSelector("table[id$='task-escalation-activator-form:activator-type-select'] label"); - click(radioButtonLabels.get(1)); - waitForElementDisplayed(By.cssSelector("input[id$=':group-expiry-activator-select_input']"), true); - type(By.cssSelector("input[id$=':group-expiry-activator-select_input']"), activatorName); - waitForElementDisplayed(By.cssSelector("span[id$=':group-expiry-activator-select_panel']"), true); - List foundRoles = - findListElementsByCssSelector("span[id$=':group-expiry-activator-select_panel'] .name-after-avatar"); - click(foundRoles.get(0)); - } - waitForElementEnabled(By.cssSelector("button[id$=':task-escalation-activator-form:assign-task-command']"), true, DEFAULT_TIMEOUT); - clickByCssSelector("button[id$=':task-escalation-activator-form:assign-task-command']"); - waitForElementDisplayed(By.cssSelector("div[id$='task-escalation-activator-dialog']"), false); - } - } - - private void clickOnEditEscaltionEditIcon() { - waitForElementDisplayed(By.className("task-expiry-activator-edit"), true); - clickByCssSelector("a[class$='task-expiry-activator-edit']"); - waitForElementDisplayed(By.cssSelector("form[id$=':task-escalation-activator-form']"), true); - } - - public boolean canChangeEscalationActivator() { - try { - return isElementDisplayed(findElementByClassName("task-expiry-activator-edit")); - } catch (NoSuchElementException ex) { - return false; - } - } - - public String getAfterEscalation() { - return findElementByClassName("task-expiry-activator-name").getText(); - } - - public void waitForIFrameWidgetLoad() { - driver.switchTo().frame("custom-widget-iframe"); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector(".container.frame").isDisplayed()); - } - - public void waitForIFrameURLWidgetLoad() { - driver.switchTo().frame("custom-widget-iframe-url"); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("a[href='https://www.axonivy.com']").isDisplayed()); - } - - public WebElement getSharePageButtonElement() { - return findElementByCssSelector("[id$=':share-page-button']"); - } - - public String getTaskUuid() { - return findElementByCssSelector("a[id$='show-more-note-link']").getAttribute("href").split("uuid=")[1]; - } - - public void waitForNoteTableDisplayed() { - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("div[id$=':task-note-table']").isDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplateIFramePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplateIFramePage.java deleted file mode 100644 index ce0711a90cf..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplateIFramePage.java +++ /dev/null @@ -1,88 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class TaskTemplateIFramePage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('task-template-title')"; - } - - public void openCaseInfo() { - clickByCssSelector("#horizontal-case-info"); - } - - @SuppressWarnings("deprecation") - public void inputDataCreateInvestmentTask() { - type(By.id("form:invested-amount"), "12345"); - clickByCssSelector("button[id$='form:save-btn']"); - switchOutIFrame(); - waitAjaxIndicatorDisappear(); - } - - public void switchToIFrame(String nameOrId) { - driver.switchTo().frame(nameOrId); - } - - public void switchOutIFrame() { - driver.switchTo().defaultContent(); - } - - @SuppressWarnings("deprecation") - public void approveInvestmentTask() { - waitForElementDisplayed(By.xpath("//label[contains(text(),'Approve')]"), true); - click(findElementByXpath("//label[contains(text(),'Approve')]")); - type(By.cssSelector("textarea[id$='approval-note']"), "text"); - clickByCssSelector("button[id$='approve-btn']"); - switchOutIFrame(); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void proceedTaskInCaseLevelIFrame() { - waitForElementDisplayed(By.xpath("//span[contains(text(),'Proceed')]"), true); - click(findElementByXpath("//span[contains(text(),'Proceed')]")); - switchOutIFrame(); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void proceedSerenityTaskTemplate() { - waitForElementDisplayed(By.cssSelector("button[id^='form']"), true); - clickByCssSelector("button[id^='form']"); - switchOutIFrame(); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void proceedDeprecateModenaTaskTemplate() { - waitForElementDisplayed(By.xpath("//span[contains(text(),'Proceed')]"), true); - type(By.cssSelector("input[id$='form:input']"), "input text"); - type(By.cssSelector("textarea[id$='form:comment-area']"), "comment"); - click(findElementByXpath("//span[contains(text(),'Proceed')]")); - switchOutIFrame(); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void proceedDeprecatedTaskTemplate() { - waitForElementDisplayed(By.xpath("//span[contains(text(),'Proceed')]"), true); - type(By.cssSelector("input[id$='form:input']"), "input text"); - type(By.cssSelector("textarea[id$='form:comment-area']"), "comment"); - click(findElementByXpath("//span[contains(text(),'Proceed')]")); - switchOutIFrame(); - waitAjaxIndicatorDisappear(); - } - - public boolean isIFrameTagDisplayed() { - return isElementPresent(By.cssSelector("iframe[id*='iFrame']")); - } - - public NewDashboardPage clickSubmitButton() { - clickByCssSelector("button[id$='button-submit']"); - switchToDefaultContent(); - return new NewDashboardPage(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplatePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplatePage.java deleted file mode 100644 index f6316d13365..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskTemplatePage.java +++ /dev/null @@ -1,340 +0,0 @@ -package portal.guitest.page; - -import java.util.List; -import java.util.stream.IntStream; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.Sleeper; -import portal.guitest.common.WaitHelper; - -public class TaskTemplatePage extends TemplatePage { - - private static final String ADHOC_HISTORY_TABLE_CSS_SELECTOR = "div[id*='adhoc-task-history-table'] table>tbody>tr"; - private static final String CASE_INFO_IFRAME_ID = "i-frame-case-details"; - - @Override - protected String getLoadedLocator() { - return "id('content-container')"; - } - - public void openCaseInfo() { - clickByCssSelector("#horizontal-case-info"); - waitForElementDisplayed(By.cssSelector("[id$='i-frame-case-details']"), true); - driver.switchTo().defaultContent(); - } - - public void switchToCaseInfoIframe() { - WaitHelper.waitForIFrameAvailable(driver, CASE_INFO_IFRAME_ID); - } - - public void clickOnAdditionalBusinessDetailLink() { - switchToCaseInfoIframe(); - clickByCssSelector("[id$=':action-group:case-details-action-link']"); - waitForElementDisplayed(By.cssSelector("[id$=':action-group:action-steps-panel']"), true); - clickByCssSelector("a[id$=':action-group:show-additional-case-details-link']"); - } - - public boolean containsCaseDetails() { - WebElement caseDetails = findDisplayedElementByCssSelector("div[id$='case-details-panel']"); - return caseDetails.isDisplayed(); - } - - public void addNewNote(String content) { - switchToCaseInfoIframe(); - clickByCssSelector("a[id$='add-note-command']"); - waitForElementDisplayed(By.cssSelector("div[id$='add-note-dialog']"), true); - findElementByCssSelector("textarea[id$='note-content']").sendKeys(content); - int beginCounts = countNoteItems(); - clickByCssSelector("button[id$='save-add-note-command']"); - WaitHelper.assertTrueWithWait(() -> countNoteItems() != beginCounts); - } - - public void openDocumentUploadingDialog() { - switchToCaseInfoIframe(); - waitForElementDisplayed(By.cssSelector("a[id$='add-document-command']"), true); - click(By.cssSelector("a[id$='add-document-command']")); - waitForElementDisplayed(By.cssSelector("div[id$='document-upload-dialog']"), true); - } - - public Boolean isDocumentUploadingDialogDisplayed() { - return findElementByCssSelector("div[id$='document-upload-dialog']").isDisplayed(); - } - - public void openFinishedTaskInHistoryArea() { - WebElement element = findElementById("case-item:history:show-more-note-link"); - String url = element.getAttribute("href"); - ((JavascriptExecutor) driver).executeScript("window.open('" + url + "','_blank');"); - } - - public int countNoteItems() { - return findListElementsByCssSelector("a[id$=':note-link']").size(); - } - - public int countHistoryItems() { - return findListElementsByCssSelector("a[id$='show-task-note-link']").size(); - } - - public int countRelatedTasks() { - switchToCaseInfoIframe(); - waitForElementDisplayed(By.cssSelector("td.related-task-name-column"), true); - return findListElementsByCssSelector("td.related-task-name-column").size(); - } - - public TaskDetailsPage openRelatedTaskInList(String taskName) { - switchToCaseInfoIframe(); - Integer index = getTaskRowIndex(taskName); - waitForElementDisplayed(By.cssSelector("td.related-task-name-column"), true); - findListElementsByCssSelector("td.related-task-name-column").get(index).click(); - return new TaskDetailsPage(); - } - - public void startSideStep() { - String actionPanelId = "horizontal-task-action-form:horizontal-task-action-menu"; - waitForElementDisplayed(By.id(actionPanelId), true); - click(findElementByClassName("side-step-item")); - waitForElementDisplayed(By.id("sidestep-task-reset-confirmation-dialog"), true); - click(findElementById("side-step-start-ok")); - new NewDashboardPage(); - } - - public int countSideSteps() { - String sideStepPanelId = "side-steps-panel"; - waitForElementDisplayed(By.id(sideStepPanelId), true); - return findListElementsByCssSelector("a[id$='side-step-item']").size(); - } - - public void clickCancelLink() { - click(By.linkText("Cancel")); - } - - public void clickResetLink() { - click(By.linkText("Reset")); - } - - public void showNoteHistory() { - click(driver.findElement(By.cssSelector("a[id$='show-more-note-link']"))); - } - - public String getCaseName() { - driver.switchTo().defaultContent(); - return findElementByCssSelector("span[id$='case-info-dialog_title']").getText().split(":")[1].trim(); - } - - public String getCaseId() { - switchToCaseInfoIframe(); - return findElementByCssSelector("span[id$='case-id']").getText(); - } - - public void clickAdhocCreationButton() { - clickTaskActionMenu(); - clickOnStartAdhocLink(); - } - - @SuppressWarnings("deprecation") - public void clickAdhocOkButton() { - clickByCssSelector("button[id$='start-adhoc-ok-button']"); - waitAjaxIndicatorDisappear(); - } - - public boolean isShowAdhocHistoryBtnNotExist() { - String adhocHistoryBtnCSSSelection = "a[id$='show-adhoc-history']"; - return driver.findElements(By.cssSelector(adhocHistoryBtnCSSSelection)).isEmpty(); - } - - public boolean isStartAdhocBtnNotExist() { - String startAdhocBtnCSSSelection = "a[id$='start-adhoc']"; - return driver.findElements(By.cssSelector(startAdhocBtnCSSSelection)).isEmpty(); - } - - @SuppressWarnings("deprecation") - public boolean isAdhocHistoryDialogExistWhenOpenTaskFirstTime() { - waitAjaxIndicatorDisappear(); - return findElementByCssSelector("div[id$='adhoc-task-history-dialog']").isDisplayed(); - } - - public boolean isAdhocHistoryDialogExist() { - return findElementByCssSelector("div[id$='adhoc-task-history-dialog']").isDisplayed(); - } - - @SuppressWarnings("deprecation") - public void clickShowAdhocHistoryBtn() { - clickByCssSelector("#horizontal-task-actions"); - waitForElementDisplayed(By.cssSelector("a[id$='show-adhoc-history']"), true); - clickByCssSelector("a[id$='show-adhoc-history']"); - waitAjaxIndicatorDisappear(); - } - - public String getTaskNameOfAdhocHistoryRow(int index) { - WebElement row = driver.findElements(By.cssSelector(ADHOC_HISTORY_TABLE_CSS_SELECTOR)).get(index); - return row.findElements(By.xpath("td")).get(2).getText(); - } - - public String getCommentOfAdhocHistoryRow(int index) { - WebElement row = driver.findElements(By.cssSelector(ADHOC_HISTORY_TABLE_CSS_SELECTOR)).get(index); - return row.findElements(By.xpath("td")).get(3).getText(); - } - - @SuppressWarnings("deprecation") - public void closeAdhocHistoryDialog() { - clickByCssSelector("button[id$='close-adhoc-dialog-button']"); - waitAjaxIndicatorDisappear(); - } - - public String getAdhocCreationMessage() { - String adhocCreationMessageCSSSelector = "div[id$='adhoc-creation-message']"; - return findDisplayedElementByCssSelector(adhocCreationMessageCSSSelector).getText(); - } - - public TaskWidgetPage clickSubmitButton() { - clickOnSubmitButton(); - return new TaskWidgetPage(); - } - - public void clickOnSubmitButton() { - clickByCssSelector("button[id$='button-submit']"); - } - - public TaskWidgetPage clickCancelAndLeftButton() { - clickByCssSelector("a[id$='button-cancel']"); - return new TaskWidgetPage(); - } - - public void clickCancelButton() { - clickByCssSelector("a[id$='button-cancel']"); - } - - public void clickTaskActionMenu() { - clickByCssSelector("button[id$='horizontal-task-actions']"); - waitForElementDisplayed(By.cssSelector("[id$=':horizontal-task-action-menu']"), true); - } - - public void clickOnStartAdhocLink() { - waitForElementDisplayed(By.cssSelector("div[id$='horizontal-task-action-form:horizontal-task-action-menu']"), true); - clickByCssSelector("a[id$='start-adhoc']"); - waitForElementDisplayed(By.cssSelector("div[id$='adhoc-task-reset-confirmation-dialog_content']"), true); - } - - public void clickChatGroup() { - String chatGroup = "a[id$='chat-group']"; - waitForElementDisplayed(By.cssSelector(chatGroup), true); - clickByCssSelector(chatGroup); - } - - @SuppressWarnings("deprecation") - public void joinProcessChatAlreadyCreated() { - waitForElementDisplayed(By.id("chat-group-join-form:chat-group-join-button"), true); - click(By.id("chat-group-join-form:chat-group-join-button")); - waitAjaxIndicatorDisappear(); - } - - public void inputFields(String employee, String from, String to, String representation) { - type(By.id("leave-request:fullname"), employee); - type(By.id("leave-request:from_input"), from); - type(By.id("leave-request:to_input"), to); - type(By.id("leave-request:substitute"), representation); - } - - public boolean isTaskNameDisplayed() { - return isElementDisplayedById("title"); - } - - public boolean isCaseInfoButtonDisplayed() { - return isElementDisplayedById("horizontal-case-info"); - } - - public boolean isTaskActionDisplayed() { - return isElementDisplayedById("horizontal-task-actions"); - } - - public WebElement getAddMemberToChatDialog() { - waitForElementDisplayed(By.id("chat-assignee-dialog"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "chat-assignee-selection-form\\\\:chat-user-selection-component\\\\:chat-user-selection_input", ID_PROPERTY); - return findElementById("chat-assignee-dialog"); - } - - public void clickCreateGroupChatBtn() { - waitForElementDisplayed(By.id("chat-assignee-selection-form:chat-group-create-button"), true); - click(By.id("chat-assignee-selection-form:chat-group-create-button")); - waitForElementDisplayed(By.id("chat-assignee-selection-form:chat-group-create-button"), false); - } - - public String getTaskName() { - return getTextOfCurrentBreadcrumb().replace("Task: ", ""); - } - - public void clickLeaveTaskOnWarningDialog() { - By leaveButton = By.id("task-leave-warning-component:leave-button"); - waitForElementDisplayed(leaveButton, true); - click(leaveButton); - } - - public TaskWidgetPage finishCreateInvestmentTask() { - WaitHelper.waitForIFrameAvailable(driver, "iFrame"); - waitForElementDisplayed(By.id("form:invested-amount"), true); - type(By.id("form:invested-amount"), "1"); - click(By.id("form:save-btn")); - driver.switchTo().defaultContent(); - WaitHelper.waitForPresenceOfElementLocatedInFrame(driver, "[id$='global-search-component:global-search-data']"); - return NavigationHelper.navigateToTaskList(); - } - - public NewDashboardPage backToHomeInIFrameApprovalTask() { - driver.switchTo().frame("iFrame"); - waitForElementDisplayed(By.id("content-form:home-btn"), true); - click(By.id("content-form:home-btn")); - driver.switchTo().defaultContent(); - return new NewDashboardPage(); - } - - public TaskWidgetPage finishIFrameReviewTask() { - waitForCloseButtonDisplayAfterInputedAprrovalNote("1"); - closeReviewPage(); - return new TaskWidgetPage(); - } - - public String getTaskNameOutsideIFrameWithSkipTaskList() { - String taskNameOutIFrameCssSelector = "span[id$='title']"; - String approveTaskNameOutIFrame = findDisplayedElementByCssSelector(taskNameOutIFrameCssSelector).getText(); - waitForCloseButtonDisplayAfterInputedAprrovalNote("1"); - driver.switchTo().defaultContent(); - WaitHelper.assertTrueWithWait(() -> !approveTaskNameOutIFrame - .equals(findDisplayedElementByCssSelector(taskNameOutIFrameCssSelector).getText())); - return findDisplayedElementByCssSelector(taskNameOutIFrameCssSelector).getText(); - } - - private void waitForCloseButtonDisplayAfterInputedAprrovalNote(String approvalNote) { - driver.switchTo().frame("iFrame"); - waitForElementDisplayed(By.id("content-form:approve-btn"), true); - type(By.id("content-form:content-tab-view:approval-note"), approvalNote); - click(By.id("content-form:approve-btn")); - waitForElementDisplayed(By.id("content-form:close-btn"), true); - } - - private void closeReviewPage() { - click(By.id("content-form:close-btn")); - driver.switchTo().defaultContent(); - } - - public boolean isCategoryColumnDisplayed() { - return findElementByCssSelector("td.category-column").isDisplayed(); - } - - public void waitForChatServiceReady() { - Sleeper.sleep(3000); // chat service are not loading at the beginning, wait a bit for service initialize - } - - public void waitForChartAssigneeDialogDisplay() { - waitForElementDisplayed(By.id("chat-assignee-dialog"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "chat-assignee-selection-form\\\\:chat-user-selection-component\\\\:chat-user-selection_input", ID_PROPERTY); - } - - public Integer getTaskRowIndex(String taskName) { - List taskNames = findListElementsByCssSelector(".task-name-value"); - int taskIndex = IntStream.range(0, taskNames.size()).filter(i -> taskNames.get(i).getText().equals(taskName)).findFirst().getAsInt(); - return taskIndex; - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskWidgetPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskWidgetPage.java deleted file mode 100644 index fa5bdb8033d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TaskWidgetPage.java +++ /dev/null @@ -1,953 +0,0 @@ -package portal.guitest.page; - -import static portal.guitest.common.WaitHelper.assertTrueWithWait; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebElement; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.TaskState; -import portal.guitest.common.WaitHelper; - -public class TaskWidgetPage extends TemplatePage { - - private String taskWidgetId; - private static final String TASK_ACTION = "horizontal-task-actions"; - private static final String CLASS = "class"; - private static final String ID_END = "*[id$='"; - private static final String TASK_STATE_COMPONENT_ID = - "task-widget:task-list-scroller:%d:task-item:task-state-component:task-state"; - private static final String KEYWORD_FILTER_SELECTOR_EXPANDED_MODE = - "input[id='task-widget:expanded-mode-filter-form:expanded-mode-filter-container:ajax-keyword-filter']"; - - public TaskWidgetPage() { - this("task-widget"); - } - - public TaskWidgetPage(String taskWidgetId) { - this.taskWidgetId = taskWidgetId; - } - - @Override - protected String getLoadedLocator() { - return "//*[contains(@id,'task-widget:task-view')]"; - } - - public TaskDetailsPage openTaskDetails(int index) { - waitForElementDisplayed(By.cssSelector("div.js-task-start-list"), true); - return clickOnTaskEntryInFullMode(index); - } - - public TaskDetailsPage openTaskDetailsFromActionMenu(int index) { - sideStepMenuOnActionButton(index); - String detailOptionCssSelector = "a[id$='additional-options:task-open-detail-command']"; - waitForElementDisplayed(By.cssSelector(detailOptionCssSelector), true); - click(By.cssSelector(detailOptionCssSelector)); - return new TaskDetailsPage(); - } - - public void showNoteHistory() { - click(driver.findElement(By.cssSelector("a[id$='show-more-note-link']"))); - } - - private TaskDetailsPage clickOnTaskEntryInFullMode(int index) { - clickByCssSelector("div[id$='" + index + "\\:task-item\\:task-info']"); - return new TaskDetailsPage(); - } - - public TaskTemplatePage startTask(int index) { - waitTaskAppearThenClick(index); - waitForElementPresent(By.id(TASK_ACTION), true); - return new TaskTemplatePage(); - } - - public String getTaskIdOfRow(int taskRowIndex) { - return findElementById( - String.format("task-widget:task-list-scroller:%d:task-item:task-id-component:task-id", taskRowIndex)).getText(); - } - - public TaskTemplatePage startTaskWithouWaitForTaskActionPresent(int index) { - waitTaskAppearThenClick(index); - return new TaskTemplatePage(); - } - - public void startDeprecatedTaskTemplate(int index) { - waitTaskAppearThenClick(index); - waitForElementPresent(By.id("task-actions"), true); - } - - public boolean isTaskDelegateOptionDisable(int index) { - sideStepMenuOnActionButton(index); - waitForElementDisplayed(By.id(taskWidgetId + ":task-list-scroller:" + index - + ":task-item:task-action:additional-options:task-delegate-command"), true); - WebElement delegateButton = findElementById(taskWidgetId + ":task-list-scroller:" + index - + ":task-item:task-action:additional-options:task-delegate-command"); - return delegateButton.getAttribute(CLASS).contains("ui-state-disabled"); - } - - public boolean isTaskDelegateOptionDisable(String taskName) { - int index = 1; - List taskElements = - findListElementsByCssSelector("span[id$=':task-item:task-name-component:task-name']"); - for (int i = 0; i < taskElements.size(); i++) { - if (taskElements.get(i).getText().equals(taskName)) { - index = i; - break; - } - } - - return isTaskDelegateOptionDisable(index); - } - - public int countTasks() { - List taskElements = findListElementsByCssSelector("div[class*='task-start-list-item']"); - return taskElements.size(); - } - - private void waitForNumberOfTasks(int... expectedNumberOfTasksAfterFiltering) { - int expectedNumber = getExpectedNumberOfTasks(expectedNumberOfTasksAfterFiltering); - WaitHelper.assertTrueWithWait(() -> this.countTasks() == expectedNumber); - } - - private int getExpectedNumberOfTasks(int... expectedNumberOfTasksAfterFiltering) { - int expectedNumber; - if (expectedNumberOfTasksAfterFiltering.length == 0) { - expectedNumber = 1; - } else { - expectedNumber = expectedNumberOfTasksAfterFiltering[0]; - } - return expectedNumber; - } - - public void filterTasksInExpandedModeBy(String keyword, int... expectedNumberOfTasksAfterFiltering) { - waitForElementDisplayed(By.cssSelector(KEYWORD_FILTER_SELECTOR_EXPANDED_MODE), true); - WebElement keywordFilter = findElementByCssSelector(KEYWORD_FILTER_SELECTOR_EXPANDED_MODE); - keywordFilter.clear(); - keywordFilter.sendKeys(keyword); - waitForNumberOfTasks(expectedNumberOfTasksAfterFiltering); - } - - public CaseDetailsPage openRelatedCaseOfTask() { - click(findElementByCssSelector("a[id$='related-case']")); - return new CaseDetailsPage(); - } - - public String getRelatedCase() { - WebElement relatedCaseLink = findElementByCssSelector("a[id$='related-case']"); - return relatedCaseLink.getText(); - } - - public void sideStepMenuOnActionButton(int index) { - String actionButton = - String.format("[id$='%d\\:task-item\\:task-action\\:additional-options\\:task-side-steps-menu']", index); - clickByCssSelector(actionButton); - String actionPanel = String.format("task-widget:task-list-scroller:%d:task-item:task-action:additional-options:side-steps-panel", index); - waitForElementDisplayed(By.id(actionPanel), true); - } - - public TaskTemplatePage clickOnSideStepAction(int taskIndex, int sideStepIndex) { - String sideStepsId = String.format( - "task-widget:task-list-scroller:%d:task-item:task-action:additional-options:task-additional-actions", - taskIndex); - WebElement sideStepPanel = findElementByCssSelector("[id$='" + sideStepsId + "']"); - List sideSteps = sideStepPanel.findElements(By.className("option-item")); - click(sideSteps.get(sideStepIndex)); - return new TaskTemplatePage(); - } - - public boolean isMoreButtonDisplayed(int taskId) { - String moreButton = String.format( - taskWidgetId + ":task-list-scroller:%d:task-item:task-action:additional-options:task-side-steps-menu", taskId); - return isElementDisplayedById(moreButton); - } - - public void reserveTask(int taskId) { - String reserveCommandButton = String.format( - taskWidgetId + ":task-list-scroller:%d:task-item:task-action:additional-options:task-reserve-command", taskId); - waitForElementDisplayed(By.id(reserveCommandButton), true); - click(findElementById(reserveCommandButton)); - } - - public void resetTask(int taskId) { - String resetCommandButton = String.format( - taskWidgetId + ":task-list-scroller:%s:task-item:task-action:additional-options:task-reset-command", taskId); - waitForElementDisplayed(By.id(resetCommandButton), true); - click(findElementById(resetCommandButton)); - } - - public boolean isTaskStartEnabled(int taskId) { - String startCommandButton = - String.format(taskWidgetId + ":task-list-scroller:%d:task-item:task-action:task-action-component", taskId); - WebElement element = findElementById(startCommandButton); - return !element.getAttribute(CLASS).contains("ui-state-disabled"); - } - - public TaskState getTaskState(int taskRowIndex) { - WebElement stateCell = findElementById(String.format(TASK_STATE_COMPONENT_ID, taskRowIndex)); - if (stateCell != null) { - String stateClass = stateCell.findElement(By.className("task-state")).getAttribute(CLASS); - String[] stateClasses = stateClass.trim().split(" "); - String state = Stream.of(stateClasses).filter(clazz -> clazz.endsWith("-task-state")).findFirst().orElse(""); - return TaskState.fromClass(state); - } - return null; - } - - public String getTaskStateTooltip(int taskRowIndex) { - WebElement stateTooltip = findElementById(String.format("task-widget:task-list-scroller:%d:task-item:task-state-component:state-tooltip", taskRowIndex)); - if (stateTooltip != null) { - WebElement stateContent = findChildElementByClassName(stateTooltip, "ui-tooltip-text"); - return stateContent.getAttribute("innerText"); - } - return StringUtils.EMPTY; - } - - public boolean isTaskPriorityChangeComponentPresented(int index) { - return isElementPresent(By.id(String.format( - taskWidgetId + ":task-list-scroller:%d:task-item:general-info:priority-form:edit-priority-inplace", index))); - } - - public boolean isTaskNameChangeComponentPresented(int index) { - return isElementPresent(By.id( - String.format(taskWidgetId + ":task-list-scroller:%d:task-item:task-name-edit-form:task-name-input", index))); - } - - public void changeDescriptionOfTask(String description) { - clickByCssSelector("a[id$=':task-detail-description:edit-description-link']"); - waitForElementDisplayed(By.cssSelector("[id$=':task-detail-description-form:task-description-inplace_content']"), true); - WebElement taskNameInput = findElementByCssSelector("textarea[id$=':task-description-input']"); - waitForElementDisplayed(taskNameInput, true); - taskNameInput.clear(); - taskNameInput.sendKeys(description); - clickByCssSelector("span[id$=':task-description-inplace_editor'] .ui-inplace-save"); - waitForElementDisplayed(findElementByCssSelector("[id$='task-description-output']"), true); - } - - public String getTaskDescription() { - return findElementByCssSelector("[id$='task-description-output'] .task-detail-description-output").getText(); - } - - public String getTaskCategory() { - return findElementByCssSelector("span[id$='task-category']").getText(); - } - - public String getCaseCategory() { - return findElementByCssSelector("span[id$='case-category']").getText(); - } - - public String getPriorityOfTask(int row) { - String priorityClassName = findElementByCssSelector("span[id$='" + row +":task-item:task-priority-component:task-priority'] > span > i").getAttribute("class"); - if (priorityClassName.contains("low-priority")) { - return "low"; - } else if (priorityClassName.contains("normal-priority")) { - return "normal"; - } else if (priorityClassName.contains("high-priority")) { - return "high"; - } else { - return "exception"; - } - } - - public boolean isTaskListColumnExist(String columnHeaderText) { - String taskListHeaderSelector = taskWidgetId + ":task-widget-sort-menu"; - waitForElementDisplayed(By.id(taskListHeaderSelector), true); - WebElement taskListHeader = findElementById(taskListHeaderSelector); - for (WebElement column : taskListHeader.findElements(By.tagName("a"))) { - if (columnHeaderText.equals(column.getText())) { - return true; - } - } - return false; - } - - public void sortTaskListByColumn(String columnHeaderText, int rowIndex, String columnId, String expectedValue) { - WebElement taskListHeader = findElementById(taskWidgetId + ":task-widget-sort-menu"); - for (WebElement column : taskListHeader.findElements(By.tagName("a"))) { - if (columnHeaderText.equals(column.getText())) { - column.click(); - break; - } - } - WaitHelper.assertTrueWithWait(() -> getTaskListCustomCellValue(rowIndex, columnId).equals(expectedValue)); - } - - public void WaitUntilSortDownIconDiplayed() { - waitForElementDisplayed(By.cssSelector("i.sort-icon.fa.fa-angle-up"), true); - } - - public String getTaskListCustomCellValue(int index, String columnId) { - WebElement cell = findElementById( - String.format(taskWidgetId + ":task-list-scroller:%d:task-item:%s-component:%s", index, columnId, columnId)); - return cell.getText(); - } - - public void openTaskDelegateDialog(int index) { - sideStepMenuOnActionButton(index); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)) - .until(() -> findElementByCssSelector("a[id$='\\:task-delegate-command']").isDisplayed()); - clickByCssSelector("a[id$='\\:task-delegate-command']"); - waitForElementDisplayed(By.cssSelector("div[id$='task-delegate-dialog']"), true); - } - - public void waitUntilTaskCountDifferentThanZero() { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> getTaskCount().intValue() != 0); - } - - public boolean isDelegateTypeSelectAvailable() { - return isElementPresent(By.cssSelector("div[id$=':activator-panel']")); - } - - public boolean isDelegateTypeDisabled(int index) { - WebElement delegateTypeRadioButton = findElementByCssSelector(String.format( - "input[id$='task-widget\\:task-item-delegate-component\\:task-delegate-form\\:activator-type-select\\:%d']", - index)); - - return Optional.ofNullable(delegateTypeRadioButton.getAttribute("disabled")).isPresent(); - } - - @SuppressWarnings("deprecation") - public AdhocPage addAdhoc(int taskIndex) { - clickByCssSelector(ID_END + taskIndex + ":task-item:task-side-steps-menu']"); - waitAjaxIndicatorDisappear(); - - try { - clickByCssSelector("a.side-step-item"); - } catch (Exception e) { - clickByCssSelector("a.side-step-item"); - } - waitForElementPresent(By.id(TASK_ACTION), true); - return new AdhocPage(); - } - - /** - * Get name from task item in task scroller at specific index. Task item must not be expanded. - * - * @param index - * @return task name - */ - public String getNameOfTaskAt(int index) { - WebElement name = findElementByCssSelector(ID_END + index + ":task-item:task-name-component:task-name']"); - return name.getText(); - } - - public String getResponsibleOfTaskAt(int index) { - List responsibles = findListElementsByCssSelector(".responsible-cell .name-after-avatar"); - return responsibles.get(index).getText(); - } - - public boolean isFilterSelectionVisible() { - return isElementPresent(By.id(taskWidgetId + ":filter-selection-form:filter-selection-panel")); - } - - @SuppressWarnings("deprecation") - public void openAdvancedFilter(String filterName, String filterIdName) { - click(By.cssSelector("[id$='filter-add-action']")); - waitForElementDisplayed(By.cssSelector("[id$='" + taskWidgetId + ":filter-add-form:filter-selection']"), true); - WebElement filterSelectionElement = findElementById(taskWidgetId + ":filter-add-form:filter-selection"); - List elements = findChildElementsByTagName(filterSelectionElement, "LABEL"); - for (WebElement element : elements) { - if (element.getText().equals(filterName)) { - click(element); - click(By.cssSelector("[id$='task-widget:filter-add-form:update-filter-selected-command']")); - waitAjaxIndicatorDisappear(); - break; - } - } - waitForElementDisplayed( - By.cssSelector("span[id$='" + filterIdName + "-filter:filter-open-form:advanced-filter-item-container']"), - true); - } - - public boolean isAdvancedFilterDisplayed(String filterIdName) { - WaitHelper.waitForVisibilityOfElementLocated(driver, "span[id$='" + filterIdName + "-filter:filter-open-form:advanced-filter-item-container']"); - return isElementDisplayed( - By.cssSelector("span[id$='" + filterIdName + "-filter:filter-open-form:advanced-filter-item-container']")); - } - - public String getFilterValue(String filterId) { - WaitHelper.waitForVisibilityOfElementLocated(driver, "[id$='" + filterId + ":advanced-filter-component']"); - WebElement filterElement = - findElementByCssSelector("button[id$='" + filterId + ":filter-open-form:advanced-filter-command']"); - return filterElement.getText(); - } - - public String getStateFilterSelection(int pos) { - WebElement stateFilterSelectionElement = - findElementByCssSelector("label[for$='state-filter:filter-input-form:state-selection:" + pos + "']"); - return stateFilterSelectionElement.getText(); - } - - public List getListStateFilterSelection() { - List stateFilterSelectionElementList = - findListElementsByCssSelector("label[for*=':state-filter:filter-input-form:state-selection:']"); - return stateFilterSelectionElementList.stream().map(WebElement::getText).collect(Collectors.toList()); - } - - public void openStateFilter() { - click(By.cssSelector("button[id$='state-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("[id$='state-filter:filter-input-form:state-selection']"), - true); - } - - public void filterByDescription(String text) { - click(By.cssSelector("button[id$='description-filter:filter-open-form:advanced-filter-command']")); - WebElement descriptionInput = - findElementByCssSelector("input[id$='description-filter:filter-input-form:description']"); - enterKeys(descriptionInput, text); - click(By.cssSelector("button[id$='description-filter:filter-input-form:update-command']")); - - WaitHelper.assertTrueWithWait(() -> - findElementByCssSelector("[id$=':description-filter:filter-open-form:advanced-filter-command']").getText().contains(text)); - } - - public void filterByDate(String filterId, String fromDate, String toDate) { - click(By.cssSelector("button[id$='" + filterId + "-filter:filter-open-form:advanced-filter-command']")); - WebElement toDateInput = - findElementByCssSelector("input[id$='" + filterId + "-filter:filter-input-form:from-" + filterId + "-calendar_input']"); - enterKeys(toDateInput, fromDate); - WebElement fromDateInput = - findElementByCssSelector("input[id$='" + filterId + "-filter:filter-input-form:to-" + filterId + "-calendar_input']"); - enterKeys(fromDateInput, toDate); - click(By.cssSelector("button[id$='" + filterId + "-filter:filter-input-form:update-command']")); - } - - @SuppressWarnings("deprecation") - public void filterByCustomerName(String text) { - click(By.cssSelector( - "button[id$='" + taskWidgetId + ":customer-name-filter:filter-open-form:advanced-filter-command']")); - WebElement customerNameInput = - findElementByCssSelector("input[id$='customer-name-filter:filter-input-form:customVarChar5']"); - enterKeys(customerNameInput, text); - click(By.cssSelector("button[id$='" + taskWidgetId + ":customer-name-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - @SuppressWarnings("deprecation") - public void filterByResponsible(String text) { - waitForElementDisplayed(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']")); - WebElement responsible = - findElementByCssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']"); - type(responsible, text); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - waitForElementDisplayedByCssSelector( - "span[id$='responsible-filter:filter-input-form:responsible_panel'] .gravatar"); - click(By.cssSelector("span[id$='responsible-filter:filter-input-form:responsible_panel'] .gravatar")); - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='responsible-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void filterByStates(List selectedStates) { - waitForElementDisplayed(By.cssSelector("button[id$='state-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='state-filter:filter-open-form:advanced-filter-command']")); - - waitForElementDisplayed(By.cssSelector("[id$='state-filter:filter-input-form:state-selection']"), - true); - WebElement stateContainer = findElementByCssSelector("[id$='state-filter:filter-input-form:state-selection']"); - stateContainer.findElements(By.cssSelector("td")).forEach(checkbox -> { - WebElement label = checkbox.findElement(By.cssSelector("label")); - if (selectedStates.stream().anyMatch(state -> StringUtils.equals(state, label.getText())) && checkbox.findElement(By.cssSelector(".ui-chkbox-box.ui-state-active")) == null) { - click(checkbox.findElement(By.cssSelector(".ui-chkbox-box.ui-state-default"))); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - if (!selectedStates.stream().anyMatch(state -> StringUtils.equals(state, label.getText())) && checkbox.findElement(By.cssSelector(".ui-chkbox-box.ui-state-active")) != null) { - click(checkbox.findElement(By.cssSelector(".ui-chkbox-box.ui-state-active"))); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - }); - - click(By.cssSelector("button[id$='state-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void removeResponsibleFilter() { - waitForElementDisplayed(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']"), - true); - findElementByCssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']").click(); - findElementByCssSelector("input[id$='responsible-filter:filter-input-form:responsible_input']").clear(); - click(By.cssSelector("button[id$='responsible-filter:filter-input-form:update-command']")); - waitAjaxIndicatorDisappear(); - } - - - public void openStateFilterOverlayPanel() { - click(By.cssSelector("button[id$='state-filter:filter-open-form:advanced-filter-command']")); - } - - public String getDisplayStateInStateFilter() { - WebElement stateFilter = getStateFilterPanel(); - List elements = findChildElementsByTagName(stateFilter, "LABEL"); - List states = elements.stream().map(WebElement::getText).collect(Collectors.toList()); - return StringUtils.join(states, ","); - } - - public void clickOnTaskStatesAndApply(List states) { - openStateFilter(); - List labelList = findChildElementsByTagName(getStateFilterPanel(), "label").stream().map(WebElement::getText) - .collect(Collectors.toList()); - List statesSelectedIndex = new ArrayList<>(); - states.forEach(state -> { - int stateIndex = labelList.indexOf(state); - if (stateIndex >= 0 && stateIndex < labelList.size()) { - statesSelectedIndex.add(stateIndex); - } - }); - clickOnUnCheckSelectAllStates(); - WaitHelper.assertTrueWithWait(() -> { - return getStateFilterPanel() - .findElements(By.cssSelector("table[id$=':filter-input-form:state-selection'] div.ui-chkbox-box span.ui-chkbox-icon.ui-icon-blank")) - .size() == labelList.size(); - }); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - List checkBoxList = getStateFilterPanel() - .findElements(By.cssSelector("table[id$=':filter-input-form:state-selection'] div.ui-chkbox-box.ui-state-default")); - statesSelectedIndex.forEach(index -> { - checkBoxList.get(index).click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - }); - - click(By.cssSelector("button[id$='state-filter:filter-input-form:update-command']")); - waitForElementDisplayed(By.cssSelector("button[id$='state-filter:filter-input-form:update-command']"), false); - } - - public void clickOnUnCheckSelectAllStates() { - var selectAll = getStateFilterPanel().findElement(By.cssSelector("[id$=':filter-input-form:states-select-all']")); - if (selectAll.findElement(By.className("ui-chkbox-box")).getAttribute(CLASS_PROPERTY).contains("ui-state-active")) { - click(selectAll.findElement(By.cssSelector("span.ui-chkbox-label"))); - WaitHelper.assertTrueWithWait(() -> { - return findElementByCssSelector("[id$=':filter-input-form:states-select-all'] div.ui-chkbox-box span.ui-chkbox-icon") - .getAttribute(CLASS).contains("ui-icon-blank"); - }); - } else { - click(selectAll.findElement(By.cssSelector("span.ui-chkbox-label"))); - WaitHelper.assertTrueWithWait(() -> { - return findElementByCssSelector("[id$=':filter-input-form:states-select-all'] div.ui-chkbox-box span.ui-chkbox-icon") - .getAttribute(CLASS).contains("ui-icon-check"); - }); - clickOnUnCheckSelectAllStates(); - } - } - - private WebElement getStateFilterPanel() { - return findElementByCssSelector("div[id$='state-filter:filter-input-form:advanced-filter-panel']"); - } - - public void clickOnStartTaskLink(int index) { - String startLinkId = - String.format("a[id$='task-list-scroller:%d:task-item:task-action:task-action-component']", index); - refreshAndWaitElement(startLinkId); - click(findElementByCssSelector(startLinkId)); - } - - public void saveFilter(String filterName) { - openSaveFilterDialog(); - WebElement filterNameInput = findElementById(taskWidgetId + ":filter-save-form:save-filter-set-name-input"); - enterKeys(filterNameInput, filterName); - click(findElementById(taskWidgetId + ":filter-save-form:filter-save-command")); - waitForElementDisplayed(By.cssSelector("div[id$=':save-filter-set-dialog']"), false); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - WaitHelper.assertTrueWithWait(() -> filterName.equals(findElementByCssSelector("a[id$='filter-name']").getText())); - } - - @SuppressWarnings("deprecation") - public void saveAdminFilter(String filterName) { - openSaveFilterDialog(); - WebElement filterNameInput = findElementById(taskWidgetId + ":filter-save-form:save-filter-set-name-input"); - enterKeys(filterNameInput, filterName); - click(findElementByCssSelector("label[for='task-widget:filter-save-form:save-filter-type-radio:1']")); - click(findElementById(taskWidgetId + ":filter-save-form:filter-save-command")); - waitAjaxIndicatorDisappear(); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public WebElement openSaveFilterDialog() { - click(By.id(taskWidgetId + ":filter-save-action")); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.id(taskWidgetId + ":filter-save-form:save-filter-set-name-input"), true); - return findElementById("task-widget:save-filter-set-dialog"); - } - - public void openSavedFilters(String filterName) { - click(findElementById("task-widget:filter-selection-form:filter-name")); - waitForElementDisplayed(By.cssSelector("span[id$='private-filters']"), true); - List saveFilters = findListElementsByCssSelector("a[id$='user-defined-filter']"); - for (WebElement filter : saveFilters) { - if (filter.getText().equals(filterName)) { - click(filter); - assertTrueWithWait(() -> findElementByCssSelector(".filter-name").getText().equals(filterName)); - return; - } - } - } - - public boolean isExistedFilter(String filterName) { - clickByCssSelector("a[id$=':filter-selection-form:filter-name']"); - List saveFilters = findListElementsByCssSelector("a[id$='user-defined-filter']"); - return saveFilters.stream().anyMatch(filter -> StringUtils.equals(filter.getText(), filterName)); - } - - public String getResponsible() { - refreshAndWaitElement("button[id$='responsible-filter:filter-open-form:advanced-filter-command']"); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> findElementByCssSelector( - "button[id$='responsible-filter:filter-open-form:advanced-filter-command'] > span").getText().length() > 1); - return findElementByCssSelector("button[id$='responsible-filter:filter-open-form:advanced-filter-command'] > span") - .getText(); - } - - public String getFilterName() { - refreshAndWaitElement("a[id$='task-widget:filter-selection-form:filter-name']"); - waitForElementDisplayed(By.cssSelector("a[id$='task-widget:filter-selection-form:filter-name'] > span"), true); - WebElement filterName = findElementByCssSelector("a[id$='task-widget:filter-selection-form:filter-name'] > span"); - return filterName.getText(); - } - - public String getTaskId() { - String taskTitleCssSelection = "span[id$=':task-id']"; - String taskTitle = findElementByCssSelector(taskTitleCssSelection).getText(); - // String taskId = taskTitle.substring(taskTitle.indexOf("#") + 1, taskTitle.indexOf(")")); - return taskTitle; - } - - public boolean hasNoTask() { - WebElement noTaskMessage = findElementByCssSelector("label[class*='no-task-message']"); - return noTaskMessage.isDisplayed(); - } - - public void startTaskWithoutUI(int index) { - waitTaskAppearThenClick(index); - } - - private void waitTaskAppearThenClick(int index) { - WebElement taskStartElement = findElementById(taskWidgetId + ":task-list-scroller") - .findElements(By.className("start-task-action")).get(index); - if (taskStartElement.getAttribute("id").contains(":task-action:resume-task-action-component")) { - click(taskStartElement); - resetResumedTask(); - } else { - String cssSelector = String.format("a[id$='%d:task-item:task-action:task-action-component']", index); - refreshAndWaitElement(cssSelector); - clickByCssSelector(cssSelector); - } - } - - public void resetResumedTask() { - waitForElementDisplayed(By.cssSelector("[id$=':reset-task-dialog_content']"), true); - click(findElementByCssSelector("[id$=':reset-task-form:reset-task-button']")); - } - - public boolean isResumedTask(int index) { - List taskItems; - WebElement taskListElement = findElementById(taskWidgetId + ":task-list-scroller"); - if (taskListElement.getAttribute(CLASS).contains("compact-mode")) { - taskItems = taskListElement.findElements(By.className("compact-task-start-link")); - return taskItems.get(index).getAttribute("id").contains("compact-resumed-task-start-link"); - } - - taskItems = taskListElement.findElements(By.className("start-task-action")); - return taskItems.get(index).getAttribute("id").contains(":task-action:resume-task-action-component"); - } - - public Integer getTaskCount() { - if (isElementDisplayed(By.cssSelector(".compact-task-widget"))) { - WebElement taskTitleElement = findElementById("task-widget:task-widget-title"); - String title = taskTitleElement.findElement(By.cssSelector("span")).getText(); - String count = StringUtils.substringBetween(title, "(", ")"); - return StringUtils.isNotBlank(count) ? Integer.parseInt(count) : null; - } else { - String title = getTextOfCurrentBreadcrumb(); - String count = StringUtils.substringBetween(title, "(", ")"); - return StringUtils.isNotBlank(count) ? Integer.parseInt(count) : null; - } - } - - public boolean isTaskStateOpen(int index) { - try { - WebElement stateComponent = findElementById(String.format(TASK_STATE_COMPONENT_ID, index)); - stateComponent.findElement(By.className("open-task-state")); - } catch (NoSuchElementException e) { - return false; - } - return true; - } - - public boolean isTaskStateReserved(int index) { - try { - WebElement stateComponent = findElementById(String.format(TASK_STATE_COMPONENT_ID, index)); - stateComponent.findElement(By.className("open-task-state")); - } catch (NoSuchElementException e) { - return false; - } - return true; - } - - private boolean isTaskActionDisplayed(String action, int taskIndex) { - return isElementDisplayedById(String - .format("task-widget:task-list-scroller:%d:task-item:task-action:additional-options:%s", taskIndex, action)); - } - - public boolean isTaskResetDisplayed() { - return isTaskActionDisplayed("task-reset-command", 0); - } - - public boolean isTaskDelegateDisplayed() { - return isTaskActionDisplayed("task-delegate-command", 0); - } - - public boolean isTaskReserverDisplayed() { - return isTaskActionDisplayed("task-reserve-command", 0); - } - - public boolean isAdhocSideStepDisplayed() { - return isElementDisplayed(By.cssSelector("a[id$='adhoc-side-step-item']")); - } - - public boolean isLoadingCategories() { - return isElementDisplayed(By.cssSelector(".loading-panel")); - } - - public boolean isAllCategoriesSelected() { - waitForElementDisplayed(By.cssSelector(".filter-category-checkbox-tree"), true); - return isElementDisplayed(By.cssSelector(".filter-category-checkbox-tree .ui-treenode-selected")); - } - - public boolean isAllCategoriesUnselected() { - waitForElementDisplayed(By.cssSelector(".filter-category-checkbox-tree"), true); - return isElementDisplayed(By.cssSelector(".filter-category-checkbox-tree .ui-treenode-hasselected")); - } - - public void openCategoryFilter() { - click(By.cssSelector("button[id$='task-category-filter:filter-open-form:advanced-filter-command']")); - waitForElementDisplayed(By.cssSelector("div[id$=':task-category-filter-tree']"), true); - } - - public void toggleNoCategory() { - List categories = findListElementsByCssSelector(".filter-category-checkbox-tree .ui-tree-selectable"); - for (WebElement category : categories) { - if (category.getText().equals("[No Category]")) { - click(category); - return; - } - } - } - - public void applyCategoryFilter() { - click(By.cssSelector("button[id$='task-category-filter:filter-input-form:update-command']")); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - @SuppressWarnings("deprecation") - public void resetFilter() { - clickByCssSelector("[id$='task-widget:filter-reset-action']"); - waitAjaxIndicatorDisappear(); - clickByCssSelector("[id$='task-widget:filter-reset-command']"); - waitForElementDisplayed(By.id("task-widget:reset-filter-set-dialog"), false); - } - - public boolean isTaskDestroyEnabled(int rowIndex) { - WebElement destroyButton = findDestroyCommand(rowIndex); - return !destroyButton.getAttribute(CLASS).contains("ui-state-disabled"); - } - - public void destroyTask(int rowIndex) { - click(findDestroyCommand(rowIndex)); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public WebElement findDestroyCommand(int rowIndex) { - String destroyCommandButton = String.format( - taskWidgetId + ":task-list-scroller:%s:task-item:task-action:additional-options:task-destroy-command", - rowIndex); - waitForElementDisplayed(By.id(destroyCommandButton), true); - return findElementById(destroyCommandButton); - } - - public void confimDestruction() { - String destroyCaseDialogId = taskWidgetId + ":destroy-task-confirmation-dialog"; - waitForElementDisplayed(By.id(destroyCaseDialogId), true); - WebElement destroyConfirmationDialog = findElementById(destroyCaseDialogId); - WebElement confirmButton = findChildElementById(destroyConfirmationDialog, taskWidgetId + ":confirm-destruction"); - confirmButton.click(); - waitForJQueryAndPrimeFaces(DEFAULT_TIMEOUT); - } - - public void selectCompactSortByName(String sortName, int rowIndex, String expectedValue) { - waitForElementDisplayed(By.cssSelector("[id$='sort-task-form:sort-task-menu_items']"), true); - String compactSortFormat = "[id$='sort-task-form:sort-task-menu_items'] li[data-label*='%s']"; - clickByCssSelector(String.format(compactSortFormat, sortName)); - WaitHelper.assertTrueWithWait(() -> getCompactTaskCellValue(rowIndex).equalsIgnoreCase(expectedValue)); - } - - public String getCompactTaskCellValue(int rowIndex) { - String taskStartFormat = this.taskWidgetId + ":task-list-scroller:%d:task-item:task-start-item-view:task-start-task-name"; - return findElementById(String.format(taskStartFormat, rowIndex)).getText(); - } - - public String getSelectedSortColumn() { - return findElementByCssSelector(".js-task-widget-sort-menu.full-mode a.ui-commandlink.is-selected").getText(); - } - - public String getSelectedCompactSortLable() { - waitForElementDisplayed(By.id("task-widget:sort-task-form"), true); - return findElementByCssSelector("label[id$='task-widget:sort-task-form:sort-task-menu_label']").getText(); - } - - public WebElement getSaveFilterDialog() { - var filterId = taskWidgetId + ":filter-save-action"; - clickByCssSelector("[id$='" + filterId + "']"); - waitForElementDisplayed(By.id(taskWidgetId + ":filter-save-form:save-filter-set-name-input"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "task-widget\\\\:filter-save-form\\\\:save-filter-set-name-input", ID_PROPERTY); - return findElementById(taskWidgetId + ":save-filter-set-dialog"); - } - - public void clickColumnsButton() { - clickByCssSelector("[id$='task-widget:task-columns-configuration:task-config-command']"); - waitForElementDisplayedByCssSelector("label[for$=':columns-checkbox:3']"); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ajax-indicator\\\\:ajax-indicator-ajax-indicator_start", ID_PROPERTY); - } - - @SuppressWarnings("deprecation") - public void selectDelegateResponsible(String responsibleName, boolean isRole) { - if (isRole) { - waitForElementDisplayed(By.cssSelector("[id$=':task-delegate-form:activator-type-select']"), true); - waitForElementEnabled(By.cssSelector("[id$=':task-delegate-form:activator-type-select:1']"), true, DEFAULT_TIMEOUT); - clickByCssSelector("[for$=':task-delegate-form:activator-type-select:1']"); - waitAjaxIndicatorDisappear(); - waitForElementDisplayed(By.cssSelector("input[id$='group-activator-select_input']"), true); - type(By.cssSelector("input[id$='group-activator-select_input']"), responsibleName); - waitForElementDisplayed(By.cssSelector("span[id$='group-activator-select_panel']"), true); - List foundRoles = - findListElementsByCssSelector("span[id$='group-activator-select_panel'] .gravatar"); - click(foundRoles.get(0)); - } else { - waitForElementDisplayed(By.cssSelector("input[id$='user-activator-select_input']"), true); - type(By.cssSelector("input[id$='user-activator-select_input']"), responsibleName); - waitForElementDisplayed(By.cssSelector("span[id$='user-activator-select_panel']"), true); - List foundUsers = - findListElementsByCssSelector("span[id$='user-activator-select_panel'] .name-after-avatar"); - click(foundUsers.get(0)); - } - waitAjaxIndicatorDisappear(); - click(By.cssSelector("button[id$='proceed-task-delegate-command']")); - waitForElementDisplayed(By.cssSelector("div[id$='task-delegate-dialog']"), false); - } - - public List getActiveTaskAction(int taskIndex) { - clickOnTaskActionLink(taskIndex); - WebElement actionPanel = findElementByCssSelector(String.format( - "div[id$='task-list-scroller:%d:task-item:task-action:additional-options:side-steps-panel']", taskIndex)); - return actionPanel.findElements(By.cssSelector("a[class*='option-item']")).stream().map(WebElement::getText) - .collect(Collectors.toList()); - } - - public void clickOnTaskActionLink(int taskIndex) { - click(findElementByCssSelector(String.format( - "a[id$='task-list-scroller:%d:task-item:task-action:additional-options:task-side-steps-menu'", taskIndex))); - waitForElementDisplayed( - By.cssSelector(String.format( - "div[id$='task-list-scroller:%d:task-item:task-action:additional-options:side-steps-panel'", taskIndex)), - true); - } - - public void waitForActionGroupDisplay() { - waitForElementDisplayed(By.cssSelector("div[class='action-container']"), true); - } - - public WebElement getExportToExcelLink() { - return findElementByCssSelector("a[id$=':task-export-to-excel']"); - } - - public void clickBack() { - waitForElementDisplayed(By.id("task-widget:back-link"), true); - click(By.id("task-widget:back-link")); - - } - - public void clickExportToExcelLink() { - // Ensure that attribute is removed before downloading - JavascriptExecutor js = (JavascriptExecutor) driver; - WebElement statusDialog = driver.findElement(By.cssSelector("div[id$=':status-dialog']")); - js.executeScript("arguments[0].removeAttribute('download-status')", statusDialog); - - // click download - WebElement downloadLink = getExportToExcelLink(); - if (downloadLink != null) { - downloadLink.click(); - } - } - - public boolean isDownloadCompleted() { - WebElement statusDialog = driver.findElement(By.cssSelector("div[id$=':status-dialog']")); - WaitHelper.assertTrueWithWait(() -> StringUtils.isNotBlank(statusDialog.getAttribute("download-status"))); - return StringUtils.equals(statusDialog.getAttribute("download-status"), "completed"); - } - - public boolean isCategoryColumnDisplayed() { - List taskCategoryCells = findListElementsByCssSelector("span[id$=':task-category-cell']"); - for (WebElement categoryCell : taskCategoryCells) { - if (categoryCell.isDisplayed()) { - return true; - } - } - return false; - } - - public void openNoActivatorFilter(String filterName) { - click(By.cssSelector("[id$='filter-add-action']")); - waitForElementDisplayed(By.cssSelector(".filter-add-panel.ui-connected-overlay-enter-done"), true); - WebElement filterSelectionElement = findElementById(taskWidgetId + ":filter-add-form:filter-selection"); - List elements = findChildElementsByTagName(filterSelectionElement, "LABEL"); - for (WebElement element : elements) { - if (element.getText().equals(filterName)) { - element.click(); - click(By.cssSelector("[id$='task-widget:filter-add-form:update-filter-selected-command']")); - break; - } - } - } - - public void filterByUnavailableActivator(boolean waitForNumberOfTask) { - waitForElementDisplayed(By.cssSelector("button[id$='available-activator-filter:filter-open-form:advanced-filter-command']"), - true); - click(By.cssSelector("button[id$='available-activator-filter:filter-open-form:advanced-filter-command']")); - - waitForElementDisplayed(By.cssSelector("[id$='available-activator-filter:filter-input-form:available-activator']"), - true); - WebElement displayOnlyUnavailableTaskCheckbox = findElementByCssSelector("[id$='available-activator-filter:filter-input-form:available-activator']"); - displayOnlyUnavailableTaskCheckbox.click(); - click(By.cssSelector("button[id$='available-activator-filter:filter-input-form:update-command']")); - if (waitForNumberOfTask) { - waitForNumberOfTasks(1); - } - } - - public void clickOnProcessViewerOption() { - waitForElementDisplayed(By.cssSelector("[id$=':task-item:task-action:additional-options:side-steps-panel'].options-panel"), true); - clickByCssSelector("a[id$=':task-item:task-action:additional-options:show-process-viewer-link']"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TemplatePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TemplatePage.java deleted file mode 100644 index 45747df5b92..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/TemplatePage.java +++ /dev/null @@ -1,555 +0,0 @@ -package portal.guitest.page; - -import java.util.ArrayList; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.Keys; -import org.openqa.selenium.OutputType; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.ui.WebDriverWait; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.PortalGUITestException; -import portal.guitest.common.UrlHelpers; -import portal.guitest.common.WaitHelper; -import vn.wawa.guitest.base.page.AbstractPage; - -public abstract class TemplatePage extends AbstractPage { - - private static final int IFRAME_SCREENSHOT_FILE_SIZE_AT_MINIMUM = 10000; - private static final String TEMPLATE_PAGE_LOCATOR = "id('global-search-item')"; - protected static final String COMPONENT_PAGE_LOCATOR = "//*[contains(@id,'theme-selection')]"; - public static final String CLASS_PROPERTY = "class"; - public static final String ID_PROPERTY = "id"; - private static final String HOME_BREADCRUMB_SELECTOR = ".portal-breadcrumb .ui-menuitem-link:first-child"; - public static final String CURRENT_BREADCRUMB_SELECTOR = ".portal-breadcrumb li:last-child .ui-menuitem-link.ui-state-disabled"; - public static final String PORTAL_GLOBAL_GROWL_ID = "portal-global-growl_container"; - - public TemplatePage() { - waitForLocatorDisplayed(getLoadedLocator()); - } - - //If page load more than 45s, mark it failed by timeout - protected long getTimeOutForLocator() { - return 9L; - } - - protected void waitForLocatorDisplayed(String locator) { - waitForElementDisplayed(locator, true, getTimeOutForLocator()); - } - - @Override - public void waitForElementDisplayed(T locator, boolean expected, long timeout) { - try { - Awaitility.await().atMost(new Duration(timeout, TimeUnit.SECONDS)).until(() -> { - try { - super.waitForElementDisplayed(locator, expected, timeout); - return; - } catch (WebDriverException e) { - System.out.println("Exception when waiting for element displayed, try again."); - } - }); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public void waitForElementReallyDisplayed(T locator, boolean expected, long timeout) { - try { - Awaitility.await().atMost(new Duration(timeout, TimeUnit.SECONDS)).until(() -> { - try { - super.waitForElementDisplayed(locator, expected, timeout); - return true; - } catch (WebDriverException | NullPointerException e) { - System.out.println("Exception when waiting for element displayed, try again."); - return false; - } - }); - } catch (Exception e) { - throw new PortalGUITestException(e); - } - } - - public void waitForElementExisted(String cssSelector, boolean expected, long timeout) { - Awaitility.await().atMost(new Duration(timeout, TimeUnit.SECONDS)).until(() -> { - try { - return (findListElementsByCssSelector(cssSelector).size() != 0) == expected; - } catch (WebDriverException e) { - System.out.println("Exception when waiting for element existed, try again."); - } - return false; - }); - } - - protected boolean isIntegrationTestRun() { - return StringUtils.isNotEmpty(System.getProperty("test.engine.url")); - } - - /** - * This method cannot make sure UI is updated as expected. Instead of using this method, wait for expected UI, e.g. buttons appear, label changed... - * In case you really want to use it, ask your team first. - */ - @Deprecated - protected void ensureNoBackgroundRequest() { - ensureNoBackgroundRequest(500, 30); - } - - private void ensureNoBackgroundRequest(int minMilliSeconds, int timeOutInSeconds) { - WebDriverWait wait = new WebDriverWait(getDriver(), timeOutInSeconds, 200); - final long startTime = System.currentTimeMillis(); - Function myFunction = webDriver -> { - if (System.currentTimeMillis() - startTime < minMilliSeconds) { - return false; - } - Object ajaxQueueIsEmpty = - ((JavascriptExecutor) getDriver()).executeScript("return PrimeFaces.ajax.Queue.isEmpty()"); - if (Boolean.TRUE.toString().equalsIgnoreCase(String.valueOf(ajaxQueueIsEmpty))) { - return true; - } - return false; - }; - try { - wait.until(myFunction); - } catch (WebDriverException e) { - e.printStackTrace(); - System.out.println("ERROR when ensuring not background request"); - } - } - - @Override - protected String getLoadedLocator() { - return TEMPLATE_PAGE_LOCATOR; - } - - /** - * This method cannot make sure UI is updated as expected. Instead of using this method, wait for expected UI, e.g. buttons appear, label changed... - * In case you really want to use it, ask your team first. - */ - @Deprecated - public void waitAjaxIndicatorDisappear() { - WebElement ajaxIndicatorStartState; - try { - ajaxIndicatorStartState = findElementById("ajax-indicator:ajax-indicator-ajax-indicator_start"); - } catch (Exception e2) { - System.out.println("ERROR waitAjaxIndicatorDisappear, maybe page is reloading"); - return; - } - boolean displayed = false; - try { - displayed = ajaxIndicatorStartState.isDisplayed(); - } catch (Exception e) { - try { - displayed = ajaxIndicatorStartState.isDisplayed(); - } catch (Exception e1) { - System.out.println("Cannot check if ajax indicator is displayed"); - } - } - if (displayed) { - try { - waitForElementDisplayed(ajaxIndicatorStartState, false); - } catch (NullPointerException | PortalGUITestException e) { - System.out.println("Error when waitAjaxIndicatorDisappear"); - e.printStackTrace(); - } - } - } - - public void waitForElementDisplayed(T locator, boolean expected) { - waitForElementDisplayed(locator, expected, getTimeOutForLocator()); - } - - public void waitForElementReallyDisplayed(T locator, boolean expected) { - waitForElementReallyDisplayed(locator, expected, getTimeOutForLocator()); - } - - - public void waitForElementPresent(T locator, boolean expected) { - waitForElementPresent(locator, expected, getTimeOutForLocator()); - } - - public int countBrowserTab() { - return driver.getWindowHandles().size(); - } - - public void switchLastBrowserTab() { - String oldTab = driver.getWindowHandle(); - ArrayList tabs = new ArrayList(driver.getWindowHandles()); - tabs.remove(oldTab); - driver.switchTo().window(tabs.get(0)); - } - - public AdminSettingsPage openAdminSettings() { - clickUserMenuItem("adminui-menu-item"); - waitAjaxIndicatorDisappear(); - return new AdminSettingsPage(); - } - - public AbsencePage openAbsencePage() { - clickUserMenuItem("absence-menu-item"); - return new AbsencePage(); - } - - public ChangePasswordPage openChangePasswordPage() { - clickUserMenuItem("change-password-menu-item"); - return new ChangePasswordPage(); - } - - public UserProfilePage openMyProfilePage() { - clickUserMenuItem("user-profile"); - return new UserProfilePage(); - } - - public void clickOnMyProfile() { - clickByCssSelector("[id='user-settings-menu']"); - clickByCssSelector("[id$='user-profile']"); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("[id$=':logo-task-losing-confirmation-dialog']").isDisplayed()); - } - - public ProjectVersionPage openProjectVersionPage() { - clickUserMenuItem("project-info-menu-item"); - return new ProjectVersionPage(); - } - - private void clickUserMenuItem(String menuItemSelector) { - waitForElementDisplayed(By.id("user-settings-menu"), true); - clickByJavaScript(findElementById("user-settings-menu")); - waitForElementDisplayed(By.id(menuItemSelector), true); - clickByJavaScript(findElementById(menuItemSelector)); - WaitHelper.assertTrueWithWait(() -> !findElementById("user-setting-container").isDisplayed()); - } - - public boolean isAdminSettingsMenuItemPresent() { - return isElementPresent("id('adminui-menu-item')"); - } - - public boolean isElementDisplayedById(String id) { - try { - findElementById(id); - return true; - } catch (org.openqa.selenium.NoSuchElementException e) { - return false; - } - } - - @Override - public boolean isElementDisplayed(T locator) { - try { - return super.isElementDisplayed(locator); - } catch (Exception e) { - return false; - } - } - - public MainMenuPage openMainMenu() { - if (!isMainMenuOpen()) { - waitForElementDisplayed(By.id("left-menu"), true); - clickByCssSelector("#left-menu"); - click(By.xpath("//a[@id='user-menu-required-login:toggle-menu']")); - } - return new MainMenuPage(); - } - - public void clickOnLogo() { - openMainMenu(); - clickByCssSelector("a[id$='logo']"); - waitAjaxIndicatorDisappear(); - } - - public WebElement findDisplayedElementByCssSelector(String selector) { - waitForElementDisplayed(By.cssSelector(selector), true); - WebElement element = findElementByCssSelector(selector); - return element; - } - - public void closeMainMenu() { - findDisplayedElementByCssSelector("#left-menu"); - if (isMainMenuOpen()) { - click(By.cssSelector("a[id$='toggle-menu']")); - click(By.id("top-menu")); - waitForElementDisplayed(By.cssSelector("a[id$='logo-small']"), true); - } - } - - public void createTestingTasksInNewWindow() { - Set windows = driver.getWindowHandles(); - String hompageHandle = driver.getWindowHandle(); - - ((JavascriptExecutor) driver).executeScript("window.open();"); - Set newWindows = driver.getWindowHandles(); - - newWindows.removeAll(windows); - String newPageHandle = ((String) newWindows.toArray()[0]); - - String createTestingTasksUrl = - UrlHelpers.generateAbsoluteProcessStartLink("portal-developer-examples/162511D2577DBA88/CategoriedLeaveRequest.ivp"); - driver.switchTo().window(newPageHandle); - driver.get(createTestingTasksUrl); - - driver.switchTo().window(hompageHandle); - } - - public boolean isMainMenuOpen() { - WebElement mainMenu = findDisplayedElementByCssSelector(".layout-wrapper"); - return mainMenu.getAttribute(CLASS_PROPERTY).indexOf("static") > 0; - } - - public TaskWidgetPage openTaskList() { - return openMainMenu().selectTaskMenu(); - } - - public CaseWidgetPage openCaseList() { - return openMainMenu().selectCaseMenu(); - } - - public String getGlobalGrowlMessage() { - return findElementById(PORTAL_GLOBAL_GROWL_ID).findElement(By.cssSelector(".ui-growl-message")).getText(); - } - - public void waitForGrowlMessageDisplayClearly() { - waitForElementDisplayed(By.id(PORTAL_GLOBAL_GROWL_ID), true); - WaitHelper.assertTrueWithWait(() -> { - var growlItem = findChildElementByClassName(findElementById(PORTAL_GLOBAL_GROWL_ID), "ui-growl-item-container"); - return growlItem.getAttribute(CLASS_PROPERTY).contains("ui-state-highlight"); - }); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "ui-growl-item-container", CLASS_PROPERTY); - } - - public GlobalSearch getGlobalSearch() { - return new GlobalSearch(); - } - - public class GlobalSearch { - - private static final String GLOBAL_SEARCH_INPUT_SELECTOR = "#global-search-component\\:global-search-data"; - - public GlobalSearch() { } - - private WebElement getSearchInput() { - waitForElementDisplayed(By.cssSelector(GLOBAL_SEARCH_INPUT_SELECTOR), true); - return findElementByCssSelector(GLOBAL_SEARCH_INPUT_SELECTOR); - } - - public boolean isDisplayed() { - waitForElementDisplayed(By.cssSelector("a[id$='global-search-item']"), true); - return findElementByCssSelector("a[id$='global-search-item']").isDisplayed(); - } - - public SearchResultPage inputSearchKeyword(String keyword) { - waitForElementDisplayed(By.cssSelector(".topbar-item.search-item"), true); - clickByCssSelector("a[id$='global-search-item']"); - waitForElementDisplayed(By.cssSelector("input[id$='global-search-component:global-search-data']"), true); - click(By.cssSelector(GLOBAL_SEARCH_INPUT_SELECTOR)); - WaitHelper.typeWithRetry(new AbstractPage() { - @Override - protected String getLoadedLocator() { - return TEMPLATE_PAGE_LOCATOR; - } - }, GLOBAL_SEARCH_INPUT_SELECTOR, keyword); - getSearchInput().sendKeys(Keys.ENTER.toString()); - try { - waitForElementDisplayed(By.id("search-results-tabview"), true); - } catch (Exception e) { - System.out.println("Exception when waiting for search page displayed, press Enter again."); - getSearchInput().sendKeys(Keys.ENTER.toString()); - } - return new SearchResultPage(); - } - - public boolean isPresent() { - return isElementPresent(By.cssSelector("a[id$='global-search-item']")); - } - - public void waitUtilProcessWidgetDisplayed() { - waitForElementDisplayed(By.className("process-widget"), true); - waitForElementDisplayed(By.className("js-loading-process-list"), false); - waitForElementDisplayed(By.className("js-process-start-list-container"), true); - } - } - - public void clickByCssSelector(String cssSelector) { - waitForElementDisplayed(By.cssSelector(cssSelector), true); - click(By.cssSelector(cssSelector)); - } - - protected void refreshAndWaitElement(String cssSelector) { - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> { - if ((findListElementsByCssSelector(cssSelector).isEmpty())) { - WaitHelper.waitForNavigation(this, () -> refresh()); - return false; - } else { - return true; - } - }); - } - - public NewDashboardPage goToHomeFromBreadcrumb() { - waitForElementDisplayed(By.cssSelector(HOME_BREADCRUMB_SELECTOR), true); - click(By.cssSelector(HOME_BREADCRUMB_SELECTOR)); - return new NewDashboardPage(); - } - - public NewDashboardPage goToHomeFromBreadcrumbWithWarning() { - waitForElementDisplayed(By.cssSelector(HOME_BREADCRUMB_SELECTOR), true); - click(By.cssSelector(HOME_BREADCRUMB_SELECTOR)); - waitForElementDisplayed(By.id("user-menu-required-login:warning-before-leaving-task-component:leave-button"), true); - click(By.id("user-menu-required-login:warning-before-leaving-task-component:leave-button")); - return new NewDashboardPage(); - } - - public String getTextOfCurrentBreadcrumb() { - WebElement breadcrumb = findElementByCssSelector(CURRENT_BREADCRUMB_SELECTOR); - String result = ""; - if (CollectionUtils.isNotEmpty(breadcrumb.findElements(By.cssSelector(".js-count")))) { - result = breadcrumb.findElement(By.cssSelector(".ui-menuitem-text")).getAttribute("innerHTML") + breadcrumb.findElement(By.cssSelector(".js-count")).getAttribute("innerHTML"); - } else { - result = breadcrumb.findElement(By.cssSelector(".ui-menuitem-text")).getAttribute("innerHTML"); - } - return result; - - } - - public String getLoggedInUserFormat() { - return getText(By.cssSelector("#user-settings-menu .name-after-avatar")); - } - - public boolean isSwitchThemeLinkIconDisabled() { - waitForElementDisplayed(By.cssSelector("#theme-switcher.ui-state-disabled"), true); - return isElementDisplayed(By.cssSelector("#theme-switcher.ui-state-disabled")); - } - - public boolean isSwitchThemeToLightModeLinkIconDisplayed() { - waitForElementDisplayed(By.cssSelector("#theme-switcher .topbar-icon.pi.pi-sun"), true); - return isElementDisplayed(By.cssSelector("#theme-switcher .topbar-icon.pi.pi-sun")); - } - - public ChatPage getChat() { - waitForElementDisplayed(By.id("toggle-chat-panel-command"), true, 5); - click(findElementById("toggle-chat-panel-command")); - return new ChatPage(); - } - public WebElement getAbsenceManagementDialog() { - return findElementById("absence-management-dialog"); - } - - public WebElement getUserSettings() { - waitForElementDisplayed(By.id("user-settings-menu"), true); - click(findElementById("user-settings-menu")); - waitForElementDisplayed(By.id("logout-setting:logout-menu-item"), true); - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "user-setting-container", ID_PROPERTY); - return findElementById("user-setting-container"); - } - - public WebElement getTopBar() { - return findElementById("top-menu"); - } - - public void waitUntilLayoutWrapperDisplayed() { - waitForElementDisplayed(By.className("layout-wrapper"), true); - } - - public void waitUntilErrorMessageShowUp() { - waitForElementDisplayed(By.className("notification-container"), true); - } - - public void clickOnShowMoreLinkOfErrorMessages() { - click(findElementByCssSelector("a[class$='notification-content-action-more-details']")); - } - - public void waitUntilErrorContainerDisplayed() { - waitForElementDisplayed(By.className("error-container"), true); - } - - public boolean isWelcomeDialogExisted() { - return CollectionUtils.isNotEmpty(findListElementsByCssSelector("div[id$='welcome-portal-guide']")); - } - - public void waitForLeftMenuActive() { - waitUntilAnimationFinished(DEFAULT_TIMEOUT, "menu-item-dashboard.active-menuitem", CLASS_PROPERTY); - } - - public void clickOnLogout() { - clickByCssSelector("[id='user-settings-menu']"); - waitForElementDisplayed(By.id("logout-setting:logout-menu-item"), true); - clickByCssSelector("[id$='logout-setting:logout-menu-item']"); - WaitHelper.assertTrueWithWait(() -> findElementByCssSelector("[id$=':username']").isDisplayed()); - } - - public DashboardConfigurationPage openDashboardConfigurationPage() { - clickUserMenuItem("dashboard-configuration"); - return new DashboardConfigurationPage(); - } - - public void switchToIFrameOfTask() { - switchToDefaultContent(); - WaitHelper.waitForIFrameAvailable(driver, "iFrame"); - } - - public void switchToDefaultContent() { - driver.switchTo().defaultContent(); - } - - public void waitForIFrameContentVisible() { - waitForIFrameScreenshotSizeGreaterThan(IFRAME_SCREENSHOT_FILE_SIZE_AT_MINIMUM); - } - - public void waitForIFrameScreenshotSizeGreaterThan(long fileSizeInBytes) { - switchToDefaultContent(); - Awaitility.await().atMost(new Duration(30, TimeUnit.SECONDS)).until(() -> { - return findElementByCssSelector("iFrame").getScreenshotAs(OutputType.FILE).length() > fileSizeInBytes; - }); - switchToIFrameOfTask(); - } - - public void waitForIFrameContentVisible(String iframeId, int iframeFileSizeAtMinimum) { - switchToDefaultContent(); - Awaitility.await().atMost(new Duration(30, TimeUnit.SECONDS)).until(() -> { - return findElementById(iframeId).getScreenshotAs(OutputType.FILE).length() > iframeFileSizeAtMinimum; - }); - WaitHelper.waitForIFrameAvailable(driver, iframeId); - } - - public boolean isAnnouncementMessageNotDisplayed() { - if (driver.findElements(By.cssSelector("div[class*='announcement-message-customizable']")).size() == 0) { - return true; - } - return false; - } - - public String getEnviromentInfo() { - waitForElementDisplayed(By.cssSelector("span[id$='server-infor']"), true, 5); - return findElementByCssSelector("span[id$='server-infor']").getText(); - } - - public String getAnnouncementMessage() { - waitForElementDisplayed(By.cssSelector("div[class*='announcement-message-customizable']"), true); - return driver.findElement(By.cssSelector("div[class*='announcement-message-customizable']")).getText(); - } - - public boolean isChatDisplayed() { - if (driver.findElements(By.id("toggle-chat-panel-command")).size() == 0) { - return false; - } - return true; - } - public void waitForElementValueChanged(String cssSelector, String expectedValue) { - Awaitility.await().atMost(new Duration(DEFAULT_TIMEOUT, TimeUnit.SECONDS)).until(() -> { - try { - return expectedValue.equals(findElementByCssSelector(cssSelector).getText()); - } catch (WebDriverException e) { - System.out.println("Exception when waiting for element existed, try again."); - } - return false; - }); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserProfilePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserProfilePage.java deleted file mode 100644 index b2696665bf7..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserProfilePage.java +++ /dev/null @@ -1,150 +0,0 @@ -package portal.guitest.page; - -import java.util.List; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.WaitHelper; - -public class UserProfilePage extends TemplatePage { - - private static final String CASE_SORT_DIRECTION_SELECTION_ITEMS = "my-profile-form:case-sort-direction-selection_items"; - private static final String CASE_SORT_DIRECTION_SELECTION_LABEL = "my-profile-form:case-sort-direction-selection_label"; - private static final String CASE_SORT_DIRECTION_SELECTION = "my-profile-form:case-sort-direction-selection"; - private static final String CASE_SORT_FIELD_SELECTION_ITEMS = "my-profile-form:case-sort-field-selection_items"; - private static final String CASE_SORT_FIELD_SELECTION_LABEL = "my-profile-form:case-sort-field-selection_label"; - private static final String CASE_SORT_FIELD_SELECTION = "my-profile-form:case-sort-field-selection"; - public static final String TASK_SORT_DIRECTION_SELECTION_ITEMS = "my-profile-form:task-sort-direction-selection_items"; - private static final String TASK_SORT_DIRECTION_SELECTION_LABEL = "my-profile-form:task-sort-direction-selection_label"; - public static final String TASK_SORT_FIELD_SELECTION_ITEMS = "my-profile-form:task-sort-field-selection_items"; - private static final String TASK_SORT_FIELD_SELECTION_LABEL = "my-profile-form:task-sort-field-selection_label"; - private static final String TASK_SORT_FIELD_SELECTION = "my-profile-form:task-sort-field-selection"; - private static final String TASK_SORT_DIRECTION_SELECTION = "my-profile-form:task-sort-direction-selection"; - private static final String LANGUAGE_SELECTION_SELECTOR = - "div[id$='language-selection'] div.ui-selectonemenu-trigger"; - - private static String SHOW_TUTORIAL_XPATH = "//*[@id='my-profile-form:general-show-tutorial']/div[2]"; - - @Override - protected String getLoadedLocator() { - return "id('my-profile-form:save-settings')"; - } - - public void selectLanguage(int newLanguage) { - waitForElementDisplayed(By.cssSelector(LANGUAGE_SELECTION_SELECTOR), true); - clickByCssSelector(LANGUAGE_SELECTION_SELECTOR); - clickByCssSelector("li[id$='language-selection_" + newLanguage + "']"); - } - - public void inputFormattingLanguage(String newLanguage) { - waitForElementDisplayed(By.cssSelector(LANGUAGE_SELECTION_SELECTOR), true); - WebElement formattingLanguage = findElementByCssSelector("[id$='my-profile-form:format-language-selection_input']"); - formattingLanguage.clear(); - formattingLanguage.sendKeys(newLanguage); - } - - public NewDashboardPage save() { - saveWithoutWaitingNavigation(); - return new NewDashboardPage(); - } - - public void saveWithoutWaitingNavigation() { - WebElement save = findElementByCssSelector("button[id$='save-settings']"); - WaitHelper.waitForNavigation(new UserProfilePage(), () -> click(save)); - } - - public String getLanguageSettingTitle() { - return findElementByCssSelector("h2[id$='language-setting-title']").getText(); - } - - public boolean isSettingSwitchedOn(String cssSelector) { - WebElement inputSwitch = findElementByCssSelector(cssSelector); - return inputSwitch != null ? inputSwitch.getAttribute("class").contains("ui-inputswitch-checked") : false; - } - - public WebElement getUserSettingCard() { - return findElementById("my-profile-container"); - } - - public boolean isDisableShowTutorialCheckbox() { - WebElement checkbox = findElementByCssSelector("[id$=':general-show-tutorial']"); - return checkbox.getAttribute("class").contains("ui-state-disabled"); - } - - public void checkShowTutorial() { - WebElement checkbox = findElementByXpath(SHOW_TUTORIAL_XPATH); - if (!checkbox.getAttribute("class").contains("ui-state-active")) { - click(checkbox.findElement(By.cssSelector("span[class='ui-chkbox-label']"))); - waitForElementDisplayed(By.xpath(SHOW_TUTORIAL_XPATH + "/span[@class='ui-chkbox-icon ui-icon ui-c ui-icon-check']"), true); - } - } - - @SuppressWarnings("deprecation") - public void selectTaskSortField(String selectValue) { - waitForElementDisplayed(By.id(TASK_SORT_FIELD_SELECTION), true); - click(findElementById(TASK_SORT_FIELD_SELECTION_LABEL)); - - waitForElementDisplayed(By.id(TASK_SORT_FIELD_SELECTION_ITEMS), true); - click(findElementByXpath("//*[@id='" + TASK_SORT_FIELD_SELECTION_ITEMS + "']/li[contains(text(),'" + selectValue + "')]")); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void selectTaskSortDirection(String selectValue) { - waitForElementDisplayed(By.id(TASK_SORT_DIRECTION_SELECTION), true); - click(findElementById(TASK_SORT_DIRECTION_SELECTION_LABEL)); - - waitForElementDisplayed(By.id(TASK_SORT_DIRECTION_SELECTION_ITEMS), true); - click(findElementByXpath("//*[@id='" + TASK_SORT_DIRECTION_SELECTION_ITEMS + "']/li[contains(text(),'" + selectValue + "')]")); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void selectCaseSortField(String selectValue) { - waitForElementDisplayed(By.id(CASE_SORT_FIELD_SELECTION), true); - click(findElementById(CASE_SORT_FIELD_SELECTION_LABEL)); - - waitForElementDisplayed(By.id(CASE_SORT_FIELD_SELECTION_ITEMS), true); - click(findElementByXpath("//*[@id='" + CASE_SORT_FIELD_SELECTION_ITEMS + "']/li[contains(text(),'" + selectValue + "')]")); - ensureNoBackgroundRequest(); - } - - @SuppressWarnings("deprecation") - public void selectCaseSortDirection(String selectValue) { - waitForElementDisplayed(By.id(CASE_SORT_DIRECTION_SELECTION), true); - click(findElementById(CASE_SORT_DIRECTION_SELECTION_LABEL)); - - waitForElementDisplayed(By.id(CASE_SORT_DIRECTION_SELECTION_ITEMS), true); - click(findElementByXpath("//*[@id='" + CASE_SORT_DIRECTION_SELECTION_ITEMS + "']/li[contains(text(),'" + selectValue + "')]")); - ensureNoBackgroundRequest(); - } - - public void changeNewDashboardPageToCase() { - String newdashboardpageLabel = "my-profile-form:homepage_label"; - click(By.id(newdashboardpageLabel)); - String caseItemCssSelector = "li.ui-selectonemenu-item[data-label='Cases']"; - waitForElementDisplayed(By.cssSelector(caseItemCssSelector), true); - clickByCssSelector(caseItemCssSelector); - waitUntilTextToBePresentInElement(findElementById(newdashboardpageLabel), "Cases", getTimeOutForLocator()); - } - - public NewDashboardPage clickOnCancelLink() { - click(findElementByCssSelector("a[id^='my-profile-form:']")); - waitForPageLoaded(); - return new NewDashboardPage(); - } - - public void changeDateFormatToPattern(String pattern) { - click(By.cssSelector("label[id$=':date-format-selection_label']")); - waitForElementDisplayed(By.cssSelector("div[id$=':date-format-selection_panel']"), true); - WebElement dateFormatContainer = findElementByCssSelector("ul[id$=':date-format-selection_items']"); - List dateFormats = dateFormatContainer.findElements(By.cssSelector("li")); - for (WebElement dateFormat: dateFormats) { - if (dateFormat.getText().indexOf(pattern) > -1) { - dateFormat.click(); - break; - } - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserSelectionComponentPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserSelectionComponentPage.java deleted file mode 100644 index 05b36d3ea15..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserSelectionComponentPage.java +++ /dev/null @@ -1,72 +0,0 @@ -package portal.guitest.page; - -import java.util.List; - -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -public class UserSelectionComponentPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('form:assign-selected-user-btn')"; - } - - public WebElement getNormalUserSelectionComponent() { - return findElementById("user-by-role-component"); - } - - public WebElement getFloatingLabelUserSelectionComponent() { - return findElementById("floating-label-component"); - } - - public WebElement getAjaxEventUserSelectionComponent() { - return findElementById("item-select-with-ajax-event-component"); - } - - public String selectFirstItemForNormalUserSelectionComponent(String keyword) { - WebElement userElement = selectUserComponent("user-by-role-autocomplete", keyword); - click(userElement); - waitForElementDisplayed(By.cssSelector("span[id$='user-by-role-autocomplete_panel']"), false); - return userElement.getCssValue("data-item-value"); - } - - public String getNormalUserSelection() { - return findElementByCssSelector("input[id$='user-by-role-autocomplete_hinput']").getCssValue("value"); - } - - public String selectFirstItemForFloatingLabelUserSelectionComponent(String keyword) { - WebElement userElement = selectUserComponent("all-user-autocomplete", keyword); - click(userElement); - waitForElementDisplayed(By.cssSelector("span[id$='all-user-autocomplete_panel']"), false); - return userElement.getCssValue("data-item-value"); - } - - public String getFloatingLabelUserSelection() { - return findElementByCssSelector("input[id$='all-user-autocomplete_hinput']").getCssValue("value"); - } - - public String selectFirstItemForAjaxEventUserSelectionComponent(String keyword) { - WebElement userElement = selectUserComponent("item-select-event-for-user-selection", keyword); - click(userElement); - waitForElementDisplayed(By.id("form:item-select-event-component:item-select-event-for-user-selection-message_info-detail"), true); - return userElement.getCssValue("data-item-value"); - } - - public String getAjaxEventUserSelection() { - return findElementByCssSelector("input[id$='item-select-event-for-user-selection_hinput']").getCssValue("value"); - } - - public void openSelectionPanelForAjaxEventUserSelectionComponent(String keyword) { - type(By.cssSelector("input[id$='item-select-event-for-user-selection_input']"), keyword); - waitForElementDisplayed(By.cssSelector("span[id$='item-select-event-for-user-selection_panel']"), true); - } - - private WebElement selectUserComponent(String componentId, String keyword) { - waitForElementDisplayed(By.cssSelector("input[id$='"+componentId+"_input']"), true); - type(By.cssSelector("input[id$='"+componentId+"_input']"), keyword); - waitForElementDisplayed(By.cssSelector("span[id$='"+componentId+"_panel']"), true); - List selectionItems = findElementByCssSelector("span[id$='"+componentId+"_panel']").findElements(By.className("ui-autocomplete-item")); - return selectionItems.get(0); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserTaskWithMailFormPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserTaskWithMailFormPage.java deleted file mode 100644 index a426eb6a182..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/UserTaskWithMailFormPage.java +++ /dev/null @@ -1,39 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; - -import vn.wawa.guitest.base.client.Browser; - - -public class UserTaskWithMailFormPage extends TaskTemplatePage { - - public void selectEmailTab() { - clickByCssSelector("a[href*='mail-tab']"); - waitForElementDisplayed(By.cssSelector("div[id$='information-email:email-content_editor']"), true); - } - public void inputData(String recipient, String subject, String content) { - inputRecipient(recipient); - inputSubject(subject); - inputContent(content); - } - - private void inputRecipient(String recipient) { - findElementById("task-form:task-view:information-email:email-recipients").sendKeys(recipient); - } - - private void inputSubject(String content) { - findElementById("task-form:task-view:information-email:email-subject").sendKeys(content); - } - - private void inputContent(String content) { - WebDriver driver = Browser.getBrowser().getDriver(); - JavascriptExecutor jse = (JavascriptExecutor) driver; - jse.executeScript("document.querySelector(\"input[name='task-form:task-view:information-email:email-content_input'\").value='" - + content + "';"); - } - public void finish() { - click(By.id("task-form:ok-btn")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogFromUserProfilePage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogFromUserProfilePage.java deleted file mode 100644 index 1d86493282f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogFromUserProfilePage.java +++ /dev/null @@ -1,21 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class WorkingTaskDialogFromUserProfilePage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('task-leave-warning-component:logo-task-losing-confirmation-dialog')"; - } - - public UserProfilePage leaveTask() { - click(By.id("task-leave-warning-component:leave-button")); - return new UserProfilePage(); - } - - public UserProfilePage reserveTask() { - click(By.id("task-leave-warning-component:reserve-task-button")); - return new UserProfilePage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPage.java deleted file mode 100644 index dee658dbd60..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPage.java +++ /dev/null @@ -1,21 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class WorkingTaskDialogPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('task-leave-warning-component:logo-task-losing-confirmation-dialog')"; - } - - public NewDashboardPage leaveTask() { - click(By.id("task-leave-warning-component:leave-button")); - return new NewDashboardPage(); - } - - public NewDashboardPage reserveTask() { - click(By.id("task-leave-warning-component:reserve-task-button")); - return new NewDashboardPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPageOfApplicationMenu.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPageOfApplicationMenu.java deleted file mode 100644 index 9a117c6f227..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/page/WorkingTaskDialogPageOfApplicationMenu.java +++ /dev/null @@ -1,16 +0,0 @@ -package portal.guitest.page; - -import org.openqa.selenium.By; - -public class WorkingTaskDialogPageOfApplicationMenu extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('user-menu-required-login:warning-before-leaving-task-component:task-leave-warning-dialog')"; - } - - public NewDashboardPage leaveTask() { - click(By.id("user-menu-required-login:warning-before-leaving-task-component:leave-button")); - return new NewDashboardPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AbsenceTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AbsenceTest.java deleted file mode 100644 index 27362714999..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AbsenceTest.java +++ /dev/null @@ -1,279 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.HIDE_YEAR; - -import java.time.LocalDate; -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import ch.ivy.addon.portalkit.enums.DeputyRoleType; -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AbsencePage; -import portal.guitest.page.NewAbsencePage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TemplatePage; - -public class AbsenceTest extends BaseTest { - private static final LocalDate TODAY = LocalDate.now(); - private static final LocalDate YESTERDAY = TODAY.minusDays(1); - private static final LocalDate TOMORROW = TODAY.plusDays(1); - - @Override - @Before - public void setup() { - super.setupWithAlternativeLinkAndAccount(cleanUpAbsencesAndSubstituesLink, TestAccount.DEMO_USER); - updatePortalSetting(HIDE_YEAR.getKey(), "false"); - } - - private NewDashboardPage changeDateFormat() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - return newDashboardPage; - } - - @Test - public void whenLoginAsNormalUserThenManageAbsencesOfThatUser() { - NewDashboardPage newDashboardPage = changeDateFormat(); - AbsencePage absencePage = openAbsencePage(newDashboardPage); - createAbsenceForCurrentUser(YESTERDAY, YESTERDAY, "For travel", absencePage); - createAbsenceForCurrentUser(TODAY, TODAY, "For party", absencePage); - assertEquals(1, absencePage.countAbsences()); - absencePage.showAbsencesInThePast(true); - assertEquals(2, absencePage.countAbsences()); - } - - @Test - public void whenLoginAsAdminUserThenManageAbsencesOfAllUsers() { - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = changeDateFormat(); - AbsencePage absencePage = openAbsencePage(newDashboardPage); - createAbsenceForCurrentUser(TODAY, TODAY, "For party", absencePage); - String demoFullName = TestAccount.DEMO_USER.getFullName(); - createAbsence(demoFullName, YESTERDAY, YESTERDAY, "For travel of another user", absencePage); - createAbsence(demoFullName, TODAY, TODAY, "For party of another user", absencePage); - assertEquals(1, absencePage.countAbsences()); - } - - @Test - public void displayMessageWhenInputOverlappingAbsence() { - LocalDate chosenDay = LocalDate.now(); - LocalDate theNextDayOfChosenDay = chosenDay.plusDays(1); - NewDashboardPage newDashboardPage = changeDateFormat(); - AbsencePage absencePage = openAbsencePage(newDashboardPage); - createAbsenceForCurrentUser(chosenDay, theNextDayOfChosenDay, "Just day off", absencePage); - assertEquals(1, absencePage.countAbsences()); - - NewAbsencePage newAbsencePage = absencePage.openNewAbsenceDialog(); - newAbsencePage.input(chosenDay, theNextDayOfChosenDay, "Overlapping absence"); - newAbsencePage.proceed(); - - assertTrue(newAbsencePage.isErrorMessageDisplayed()); - assertEquals("The absence is overlapping with another absence.", newAbsencePage.getErrorMessage()); - } - - @Test - public void testDeputyAsNormalUser() { - AbsencePage absencePage = openAbsencePage(); - List personalTaskDuringAbsenceDeputyNames = Arrays.asList(TestAccount.CASE_OWNER_USER.getFullName(), TestAccount.GUEST_USER.getFullName()); - absencePage.setDeputy(personalTaskDuringAbsenceDeputyNames, DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE); - List personalTaskPermanentDeputyNames = Arrays.asList(TestAccount.ADMIN_USER.getFullName(), TestAccount.HR_ROLE_USER.getFullName()); - absencePage.setDeputy(personalTaskPermanentDeputyNames, DeputyRoleType.PERSONAL_TASK_PERMANENT); - absencePage.saveSubstitute(); - absencePage.waitForAbsencesGrowlMessageDisplay(); - assertEquals(joinDeputyNames(personalTaskDuringAbsenceDeputyNames), absencePage.getMyDeputy(absencePage.indexOfDeputyRole(DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE))); - assertEquals(joinDeputyNames(personalTaskPermanentDeputyNames), absencePage.getMyDeputy(absencePage.indexOfDeputyRole(DeputyRoleType.PERSONAL_TASK_PERMANENT))); - } - - @Test - public void testDeputyAsAdminUser() { - login(TestAccount.ADMIN_USER); - AbsencePage absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - List personalTaskDuringAbsenceDeputyNames = Arrays.asList(TestAccount.CASE_OWNER_USER.getFullName(), TestAccount.GUEST_USER.getFullName()); - absencePage.setDeputy(personalTaskDuringAbsenceDeputyNames, DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE); - List personalTaskPermanentDeputyNames = Arrays.asList(TestAccount.ADMIN_USER.getFullName(), TestAccount.HR_ROLE_USER.getFullName()); - absencePage.setDeputy(personalTaskPermanentDeputyNames, DeputyRoleType.PERSONAL_TASK_PERMANENT); - absencePage.saveSubstitute(); - absencePage.waitForAbsencesGrowlMessageDisplay(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - assertEquals(joinDeputyNames(personalTaskDuringAbsenceDeputyNames), absencePage.getMyDeputy(absencePage.indexOfDeputyRole(DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE))); - assertEquals(joinDeputyNames(personalTaskPermanentDeputyNames), absencePage.getMyDeputy(absencePage.indexOfDeputyRole(DeputyRoleType.PERSONAL_TASK_PERMANENT))); - } - - private String joinDeputyNames(List deputyNames) { - return String.join(", ", deputyNames); - } - - @Test - public void testAddDeputyInPermanentToDuringAbsence() { - login(TestAccount.ADMIN_USER); - AbsencePage absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - List deputyNames = Arrays.asList(TestAccount.CASE_OWNER_USER.getFullName()); - absencePage.setDeputy(deputyNames, DeputyRoleType.PERSONAL_TASK_PERMANENT); - absencePage.setDeputy(deputyNames, DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE, false); - assertTrue(absencePage.getChooseDeputyDialogError().startsWith("Substitute is already selected in")); - } - - @Test - public void testAddDeputyInDuringAbsenceToPermanent() { - login(TestAccount.ADMIN_USER); - AbsencePage absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - List deputyNames = Arrays.asList(TestAccount.CASE_OWNER_USER.getFullName()); - absencePage.setDeputy(deputyNames, DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE); - absencePage.setDeputy(deputyNames, DeputyRoleType.PERSONAL_TASK_PERMANENT, false); - assertTrue(absencePage.getChooseDeputyDialogError().startsWith("Substitute is already selected in")); - } - - @Test - public void testIAmDeputyFor() { - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = changeDateFormat(); - AbsencePage absencePage = openAbsencePage(newDashboardPage); - createAbsenceForCurrentUser(TOMORROW, TOMORROW, "For Family", absencePage); - - absencePage.setDeputy(Arrays.asList(TestAccount.DEMO_USER.getFullName()), 0); - absencePage.saveSubstitute(); - login(TestAccount.DEMO_USER); - absencePage = openAbsencePage(newDashboardPage); - assertTrue(absencePage.getIAMDeputyFor().contains(TestAccount.ADMIN_USER.getFullName())); - } - - private AbsencePage openAbsencePage(TemplatePage templatePage) { - return templatePage.openAbsencePage(); - } - - private AbsencePage openAbsencePage() { - return new NewDashboardPage().openAbsencePage(); - } - - private void createAbsenceForCurrentUser(LocalDate from, LocalDate till, String comment, AbsencePage absencePage) { - createAbsence("", from, till, comment, absencePage); - } - - private void createAbsence(String fullname, LocalDate from, LocalDate till, String comment, AbsencePage absencePage) { - NewAbsencePage newAbsencePage = absencePage.openNewAbsenceDialog(); - newAbsencePage.input(fullname, from, till, comment); - newAbsencePage.proceed(); - } - - @Test - public void testReadOwnAbsenceOnly() { - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadAbsencesPermission.ivp"); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantCreateAbsencePermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - createAbsenceForCurrentUser(YESTERDAY, YESTERDAY, "For travel", absencePage); - - login(TestAccount.DEMO_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadOwnAbsencesPermission.ivp"); - absencePage = openAbsencePage(); - createAbsenceForCurrentUser(YESTERDAY, YESTERDAY, "For travel", absencePage); - - login(TestAccount.GUEST_USER); - absencePage = openAbsencePage(); - absencePage.showAbsencesInThePast(true); - assertEquals(1, absencePage.countAbsences()); - } - - @Test - public void testReadAbsencesOfOtherUser() { - login(TestAccount.DEMO_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadOwnAbsencesPermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - createAbsenceForCurrentUser(YESTERDAY, YESTERDAY, "For travel", absencePage); - - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadAbsencesPermission.ivp"); - absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - absencePage.showAbsencesInThePast(true); - assertEquals(1, absencePage.countAbsences()); - } - - @Test - public void testDeleteAbsenceOfOtherUser() { - login(TestAccount.DEMO_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadOwnAbsencesPermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - createAbsenceForCurrentUser(YESTERDAY, YESTERDAY, "For travel", absencePage); - createAbsenceForCurrentUser(TODAY, TODAY, "For other reason", absencePage); - - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadAbsencesPermission.ivp"); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantDeleteAbsencePermission.ivp"); - absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - absencePage.showAbsencesInThePast(true); - assertEquals(2, absencePage.countAbsences()); - assertTrue(absencePage.canDeleteAbsence(0)); - assertTrue(absencePage.canDeleteAbsence(1)); - } - - @Test - public void testEditAbsenceOfOtherUser() { - login(TestAccount.DEMO_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadOwnAbsencesPermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - createAbsenceForCurrentUser(YESTERDAY, YESTERDAY, "For travel", absencePage); - createAbsenceForCurrentUser(TODAY, TODAY, "For other reason", absencePage); - - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantReadAbsencesPermission.ivp"); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantCreateAbsencePermission.ivp"); - absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - absencePage.showAbsencesInThePast(true); - assertEquals(2, absencePage.countAbsences()); - assertTrue(absencePage.canEditAbsence(0)); - assertTrue(absencePage.canEditAbsence(1)); - } - - @Test - public void testReadOnlyDeputyOfOtherUser() { - login(TestAccount.DEMO_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantCreateOwnSubstitutePermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - List deputyNames = Arrays.asList(TestAccount.GUEST_USER.getFullName()); - absencePage.setDeputy(deputyNames, DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE); - absencePage.saveSubstitute(); - absencePage.waitForAbsencesGrowlMessageDisplay(); - - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantCreateOwnSubstitutePermission.ivp"); - absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - assertEquals(TestAccount.GUEST_USER.getFullName(), absencePage.getMyDisabledDeputy(absencePage.indexOfDeputyRole(DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE))); - } - - @Test - public void testSelectDeputyOfOtherUser() { - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/grantCreateSubstitutePermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - List deputyNames = Arrays.asList(TestAccount.GUEST_USER.getFullName()); - absencePage.setDeputy(deputyNames, DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE); - absencePage.saveSubstitute(); - absencePage.waitForAbsencesGrowlMessageDisplay(); - assertEquals(TestAccount.GUEST_USER.getFullName(), absencePage.getMyDeputy(absencePage.indexOfDeputyRole(DeputyRoleType.PERSONAL_TASK_DURING_ABSENCE))); - } - - @Test - public void testReadOwnDeputy() { - login(TestAccount.GUEST_USER); - redirectToRelativeLink("PortalKitTestHelper/14DE09882B540AD5/denyReadSubstitutesPermission.ivp"); - AbsencePage absencePage = openAbsencePage(); - assertTrue(absencePage.isDeputySettingSectionDisplayed()); - - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - assertFalse(absencePage.isDeputySettingSectionDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdhocExpressTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdhocExpressTest.java deleted file mode 100644 index a5819655f9f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdhocExpressTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.DefaultExpresTaskPage; -import portal.guitest.page.ExpressProcessPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.WorkingTaskDialogPage; - -public class AdhocExpressTest extends BaseTest { - - private TaskWidgetPage taskWidgetPage; - private TaskTemplatePage taskTemplatePage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - } - - @Test - public void testAddAdhocForTask() { - String taskNamePrefix = "Maternity"; - String defaultTaskName1 = "Task 1"; - String defaultTaskName2 = "Task 2"; - String defaultTaskComment1 = "good"; - String defaultTaskComment2 = "it's okay"; - - //check if task Maternity exists - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy(taskNamePrefix, 1); - assertEquals(1, taskWidgetPage.countTasks()); - String taskId = taskWidgetPage.getTaskId(); - taskTemplatePage = taskWidgetPage.startTask(0); - - //create adhoc from Maternity task - assertEquals(true, taskTemplatePage.isShowAdhocHistoryBtnNotExist()); - taskTemplatePage.clickAdhocCreationButton(); - assertEquals("You may lose your work in progress and start the Ad-hoc process. Do you want to continue?", taskTemplatePage.getAdhocCreationMessage()); - taskTemplatePage.clickAdhocOkButton(); - - //create tasks in adhoc page - ExpressProcessPage expressPage = new ExpressProcessPage(); - String processName = expressPage.getProcessName(); - assertTrue(processName.startsWith(String.format("AdHoc Process for Task %s -", taskId))); - ExpressResponsible responsible = new ExpressResponsible("demo", false); - List responsibles = Arrays.asList(responsible); - expressPage.createDefaultTask(0, defaultTaskName1, responsibles); - expressPage.addNewTask(0); - expressPage.createDefaultTask(1, defaultTaskName2, responsibles); - expressPage.executeDirectly(); - - //first task of adhoc - DefaultExpresTaskPage defaultExpressTaskPage = new DefaultExpresTaskPage(); - defaultExpressTaskPage.enterTextToDefaultTask(defaultTaskComment1); - defaultExpressTaskPage.finishDefaultTask(); - - //approval task of adhoc - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy(defaultTaskName2, 1); - assertEquals(1, taskWidgetPage.countTasks()); - taskWidgetPage.startTask(0); - defaultExpressTaskPage = new DefaultExpresTaskPage(); - defaultExpressTaskPage.enterTextToDefaultTask(defaultTaskComment2); - defaultExpressTaskPage.finishDefaultTask(); - new TaskWidgetPage(); - - //check if task Maternity task - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy(taskNamePrefix, 1); - assertEquals(1, taskWidgetPage.countTasks()); - taskWidgetPage.startTask(0); - - //check adhoc history - assertEquals(true, taskTemplatePage.isAdhocHistoryDialogExistWhenOpenTaskFirstTime()); - assertEquals(defaultTaskName2, taskTemplatePage.getTaskNameOfAdhocHistoryRow(0)); - assertEquals(defaultTaskComment2, taskTemplatePage.getCommentOfAdhocHistoryRow(0)); - assertEquals(defaultTaskName1, taskTemplatePage.getTaskNameOfAdhocHistoryRow(1)); - assertEquals(defaultTaskComment1, taskTemplatePage.getCommentOfAdhocHistoryRow(1)); - - //open again by clicking adhoc dialog icon - taskTemplatePage.closeAdhocHistoryDialog(); - taskTemplatePage.clickShowAdhocHistoryBtn(); - assertEquals(true, taskTemplatePage.isAdhocHistoryDialogExist()); - taskTemplatePage.closeAdhocHistoryDialog(); - - //open Maternity task again and make sure adhoc history dialog doesn't appear - taskTemplatePage.clickOnLogo(); - WorkingTaskDialogPage dialogPage = new WorkingTaskDialogPage(); - dialogPage.leaveTask(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.startTask(0); - assertEquals(false, taskTemplatePage.isAdhocHistoryDialogExist()); - - //click adhoc creation button and check warning message - taskTemplatePage.clickAdhocCreationButton(); - assertEquals("There is already an adhoc process for this task, do you want to create another one?", taskTemplatePage.getAdhocCreationMessage()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdminSettingsTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdminSettingsTest.java deleted file mode 100644 index b257d7bc53a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AdminSettingsTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.DEFAULT_SORT_DIRECTION_OF_CASE_LIST; -import static portal.guitest.common.Variable.DEFAULT_SORT_DIRECTION_OF_TASK_LIST; -import static portal.guitest.common.Variable.DEFAULT_SORT_FIELD_OF_CASE_LIST; -import static portal.guitest.common.Variable.DEFAULT_SORT_FIELD_OF_TASK_LIST; -import static portal.guitest.common.Variable.GLOBAL_FOOTER_INFO; - -import org.junit.Test; - -import ch.ivy.addon.portalkit.enums.SortDirection; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; - -public class AdminSettingsTest extends BaseTest { - - @Test - public void whenLoginAsAdminThenAdminMenuItemDisplayed() { - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertTrue("Admin Settings menu item is not displayed", newDashboardPage.isAdminSettingsMenuItemPresent()); - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - assertTrue("Admin Settings dialog is not displayed", adminSettingsPage.isDisplayed()); - } - - @Test - public void whenLoginAsNonAdminThenAdminMenuItemNotDisplayed() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertFalse("Admin Settings menu item is displayed", newDashboardPage.isAdminSettingsMenuItemPresent()); - } - - @Test - public void testDefaultEnvironmentInfo() { - login(TestAccount.ADMIN_USER); - NewDashboardPage homePage = new NewDashboardPage(); - AdminSettingsPage adminSettingsPage = homePage.openAdminSettings(); - adminSettingsPage.setGlobalFooterInfo(); - assertTrue(homePage.getGlobalFooterInfo().contains("Wawa")); - } - - @Test - public void testCustomizedEnvironmentInfo() { - updatePortalSetting(GLOBAL_FOOTER_INFO.getKey(), "Dev Team: Wawa, Env: Dev"); - login(TestAccount.ADMIN_USER); - NewDashboardPage homePage = new NewDashboardPage(); - // Customize environment info in portal example - redirectToRelativeLinkWithEmbedInFrame(createTaskWithIframe); - - assertTrue(homePage.getGlobalFooterInfo().contains("Wawa")); - } - - @Test - public void testDefaultSortOptionsForTaskList() { - updatePortalSetting(DEFAULT_SORT_FIELD_OF_TASK_LIST.getKey(), "PRIORITY"); - updatePortalSetting(DEFAULT_SORT_DIRECTION_OF_TASK_LIST.getKey(), SortDirection.ASC.name()); - redirectToRelativeLink(cleanSessionCacheUrl); - - createTestingTasks(); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals("high", taskWidgetPage.getPriorityOfTask(0)); - assertEquals("low", taskWidgetPage.getPriorityOfTask(taskWidgetPage.countTasks() - 1)); - } - - @Test - public void testDefaultSortOptionsForCaseList() { - redirectToRelativeLink(create12CasesWithCategoryUrl); - updatePortalSetting(DEFAULT_SORT_FIELD_OF_CASE_LIST.getKey(), "NAME"); - updatePortalSetting(DEFAULT_SORT_DIRECTION_OF_CASE_LIST.getKey(), SortDirection.DESC.name()); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - - MainMenuPage mainMenuPage = taskWidgetPage.openMainMenu(); - CaseWidgetPage caseWidgetPage = mainMenuPage.openCaseList(); - assertEquals("TestCase", caseWidgetPage.getCaseNameAt(0)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AnnouncementTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AnnouncementTest.java deleted file mode 100644 index aff05beee71..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/AnnouncementTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.AnnouncementPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.UserProfilePage; - -public class AnnouncementTest extends BaseTest { - @Override - @Before - public void setup() { - super.setup(); - login(TestAccount.ADMIN_USER); - resetLanguageOfCurrentUser(); - } - - @Test - public void testNotificationLocalizationWhenChangingLanguageSetting() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - AnnouncementPage announcementPage = adminSettingsPage.openAnnouncementTab(); - announcementPage.setAnnoucement(0, "lies mich"); - announcementPage.setAnnoucement(1, "Readme1"); - announcementPage.publish(); - adminSettingsPage.clickOnbackToNewDashboardPageOnAdminSetting(); - newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - userProfilePage.selectLanguage(3); - userProfilePage.save(); - assertEquals("lies mich", newDashboardPage.getAnnouncementMessage()); - - userProfilePage = newDashboardPage.openMyProfilePage(); - userProfilePage.selectLanguage(1); - newDashboardPage = userProfilePage.save(); - assertEquals("Readme1", newDashboardPage.getAnnouncementMessage()); - } - - @Test - public void testValidationForDefaultLanguage() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - AnnouncementPage announcementPage = adminSettingsPage.openAnnouncementTab(); - announcementPage.publish(); - assertEquals("Announcement for application default language is required.", announcementPage.getInfoSummary()); - } - - @Test - public void testShouldDisplayNotification() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - newDashboardPage.waitForGrowlMessageDisplayClearly(); - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - AnnouncementPage announcementPage = adminSettingsPage.openAnnouncementTab(); - assertTrue("Admin Settings dialog is displayed", announcementPage.isDisplayed()); - - announcementPage.setAnnoucement(1, "Readme1"); - announcementPage.publish(); - adminSettingsPage.clickOnbackToNewDashboardPageOnAdminSetting(); - newDashboardPage = new NewDashboardPage(); - assertEquals("Readme1", newDashboardPage.getAnnouncementMessage()); - } - - @Test - public void testDepulishNotification() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - AnnouncementPage announcementPage = adminSettingsPage.openAnnouncementTab(); - assertTrue("Admin Settings dialog is not displayed", announcementPage.isDisplayed()); - - announcementPage.setAnnoucement(0, "Readme"); - announcementPage.setAnnoucement(1, "Readme1"); - announcementPage.setAnnoucement(2, "Readme2"); - announcementPage.setAnnoucement(3, "Readme3"); - announcementPage.publish(); - announcementPage.dePublish(); - assertTrue("Announcement is displaying ", newDashboardPage.isAnnouncementMessageNotDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BackNavigationTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BackNavigationTest.java deleted file mode 100644 index 0b4325a756d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BackNavigationTest.java +++ /dev/null @@ -1,173 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.DateTimePattern; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class BackNavigationTest extends BaseTest { - - private static final String CASE_LIST_TITLE = "Cases"; - private static final String CASE_DETAILS_TITLE = "Case Details"; - private static final String TASK_LIST_TITLE = "Tasks"; - private static final String TASK_DETAILS_TITLE = "Task Details"; - - private static final String LEAVE_REQUEST_CASE_NAME = "Leave Request"; - private static final String PAYMENT_CASE_NAME = "Create New Payment"; - private static final String PAYMENT_TASK_NAME = "Do New Payment"; - - private NewDashboardPage newDashboardPage; - private CaseDetailsPage caseDetailsPage; - private CaseWidgetPage caseWidgetPage; - private TaskDetailsPage taskDetailsPage; - private TaskWidgetPage taskWidgetPage; - - @Override - @Before - public void setup() { - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - login(TestAccount.DEMO_USER); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testEnterTaskDetailAndGoBack() { - createTestingTasks(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - assertEquals(TASK_DETAILS_TITLE, taskDetailsPage.getPageTitle()); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - assertEquals(TASK_LIST_TITLE, taskWidgetPage.getPageTitle()); - - taskDetailsPage = taskWidgetPage.openTaskDetailsFromActionMenu(0); - assertEquals(TASK_DETAILS_TITLE, taskDetailsPage.getPageTitle()); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - assertEquals(TASK_LIST_TITLE, taskWidgetPage.getPageTitle()); - } - - @Test - public void testEnterCaseDetailAndGoBack() { - createTestingTasks(); - caseWidgetPage = newDashboardPage.openCaseList(); - caseDetailsPage = caseWidgetPage.openCaseDetailsFromActionMenuByCaseName(LEAVE_REQUEST_CASE_NAME); - assertEquals(CASE_DETAILS_TITLE, caseDetailsPage.getPageTitle()); - caseWidgetPage = caseDetailsPage.goBackToCaseListFromCaseDetails(); - assertEquals(CASE_LIST_TITLE, caseWidgetPage.getPageTitle()); - } - - @Test - public void testFinishTaskFromCaseDetailAndGoBack() { - createTestingTasks(); - caseWidgetPage = newDashboardPage.openCaseList(); - - caseDetailsPage = caseWidgetPage.openCaseDetailsFromActionMenuByCaseName(LEAVE_REQUEST_CASE_NAME); - assertEquals(CASE_DETAILS_TITLE, caseDetailsPage.getPageTitle()); - - TaskDetailsPage taskDetailsPage = caseDetailsPage.openTasksOfCasePage(1); - assertEquals(TASK_DETAILS_TITLE, taskDetailsPage.getPageTitle()); - - TaskTemplatePage taskTemplatePage = taskDetailsPage.clickStartTask(); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - String yesterday = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - taskTemplatePage.inputFields("tester", yesterday, today, "tester"); - taskTemplatePage.clickOnSubmitButton(); - - caseDetailsPage = new CaseDetailsPage(); - assertEquals(CASE_DETAILS_TITLE, caseDetailsPage.getPageTitle()); - - caseWidgetPage = caseDetailsPage.goBackToCaseListFromCaseDetails(); - assertEquals(CASE_LIST_TITLE, caseWidgetPage.getPageTitle()); - } - - @Test - public void testNavigateFromTechToBusinessCase() { - redirectToRelativeLink(createNewPaymentUrl); - caseWidgetPage = newDashboardPage.openCaseList(); - - caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName(PAYMENT_CASE_NAME); - assertEquals(CASE_DETAILS_TITLE, caseDetailsPage.getPageTitle()); - - caseDetailsPage.openRelatedCaseOfBusinessCase(0); - caseDetailsPage.waitForCaseDetailsReload(); - assertEquals("Signal create New Payment", caseDetailsPage.getCaseName()); - - caseDetailsPage.clickBackButton(); - caseDetailsPage.waitForCaseDetailsReload(); - assertEquals(PAYMENT_CASE_NAME, caseDetailsPage.getCaseName()); - - caseWidgetPage = caseDetailsPage.goBackToCaseListFromCaseDetails(); - assertEquals(CASE_LIST_TITLE, caseWidgetPage.getPageTitle()); - } - - @Test - public void testNavigateAfterFinishedTaskToCaseDetails() { - redirectToRelativeLink(simplePaymentUrl); - caseWidgetPage = newDashboardPage.openCaseList(); - - caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName(PAYMENT_CASE_NAME); - assertEquals(PAYMENT_CASE_NAME, caseDetailsPage.getCaseName()); - - taskDetailsPage = caseDetailsPage.openTasksOfCasePage(1); - assertEquals(PAYMENT_TASK_NAME, taskDetailsPage.getTaskName()); - caseDetailsPage = taskDetailsPage.backToCaseDetails(); - assertEquals(PAYMENT_CASE_NAME, caseDetailsPage.getCaseName()); - - taskDetailsPage = caseDetailsPage.openTasksOfCasePage(1); - assertEquals(PAYMENT_TASK_NAME, taskDetailsPage.getTaskName()); - - TaskTemplatePage taskTemplatePage = taskDetailsPage.clickStartTask(); - taskTemplatePage.type(By.id("payment-request:fullname"), "Demo"); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - taskTemplatePage.type(By.id("payment-request:from_input"), today); - taskTemplatePage.clickOnSubmitButton(); - caseDetailsPage = new CaseDetailsPage(); - caseDetailsPage.waitForCaseDetailsReload(); - assertEquals(PAYMENT_CASE_NAME, caseDetailsPage.getCaseName()); - - caseWidgetPage = caseDetailsPage.goBackToCaseListFromCaseDetails(); - assertEquals(CASE_LIST_TITLE, caseWidgetPage.getPageTitle()); - } - - @Test - public void testNavigateAfterCancelTaskToCaseDetails() { - redirectToRelativeLink(simplePaymentUrl); - caseWidgetPage = newDashboardPage.openCaseList(); - - caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName(PAYMENT_CASE_NAME); - assertEquals(PAYMENT_CASE_NAME, caseDetailsPage.getCaseName()); - - taskDetailsPage = caseDetailsPage.openTasksOfCasePage(1); - assertEquals(PAYMENT_TASK_NAME, taskDetailsPage.getTaskName()); - - TaskTemplatePage taskTemplatePage = taskDetailsPage.clickStartTask(); - taskTemplatePage.clickCancelLink(); - taskDetailsPage = new TaskDetailsPage(); - assertEquals(PAYMENT_TASK_NAME, taskDetailsPage.getTaskName()); - taskDetailsPage.clickBackButton(); - - caseDetailsPage = new CaseDetailsPage(); - assertEquals(CASE_DETAILS_TITLE, caseDetailsPage.getPageTitle()); - - caseWidgetPage = caseDetailsPage.goBackToCaseListFromCaseDetails(); - assertEquals(CASE_LIST_TITLE, caseWidgetPage.getPageTitle()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BusinessCaseTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BusinessCaseTest.java deleted file mode 100644 index 977799c8cf2..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/BusinessCaseTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.SearchResultPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.TemplatePage.GlobalSearch; - -public class BusinessCaseTest extends BaseTest { - - private static final String TECHNICAL_CASE_NAME = "TECH: Update checkin time"; - private static final String BUSINESS_CASE_NAME = "Update checkin time"; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(businessCaseUrl); - } - - @Test - public void testOnlyDisplayBusinessCaseOnCaseList() { - - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - assertTrue(casePage.isCaseDisplayed(BUSINESS_CASE_NAME)); - assertFalse(casePage.isCaseDisplayed(TECHNICAL_CASE_NAME)); - } - - @Test - public void testOnlyDisplayBusinessCaseOnCaseListWithAdmin() { - login(TestAccount.ADMIN_USER); - - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - assertTrue(casePage.isCaseDisplayed(BUSINESS_CASE_NAME)); - assertFalse(casePage.isCaseDisplayed(TECHNICAL_CASE_NAME)); - } - - @Test - public void testOnlyDisplayBusinessCaseOnGlobalSearch() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(BUSINESS_CASE_NAME); - searchResultPage.openCaseTab(); - assertEquals(1, searchResultPage.countCase()); - assertEquals(BUSINESS_CASE_NAME, searchResultPage.getCaseResult(0)); - } - - @Test - public void testTaskOfTechnicalCaseDisplayBusinessCaseOnTaskDetails() { - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - int firstTask = 0; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(firstTask); - assertTrue(taskWidgetPage.getRelatedCase().contains(BUSINESS_CASE_NAME)); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDescriptionChangeTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDescriptionChangeTest.java deleted file mode 100644 index 901ad5b7741..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDescriptionChangeTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.UserProfilePage; - -public class CaseDescriptionChangeTest extends BaseTest { - - private NewDashboardPage newDashboardPage; - private CaseWidgetPage casePage; - - @Override - @Before - public void setup() { - super.setup(); - createTestingTasks(); - } - - @Ignore - @Test - /** - * This test is ignored because it need specific configuration on engine to run correctly - */ - public void testChangeCaseDescription() { - var caseNameEn = "Leave Request"; - var caseNameGer = "Urlaubsantrag"; - var newCaseDescriptionEn = "New Case Description - English"; - var newCaseDescriptionGer = "New Case Description - German"; - login(TestAccount.ADMIN_USER); - newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - CaseDetailsPage detailsPage = casePage.openDetailsOfCaseHasName(caseNameEn); - detailsPage.changeCaseDescription(newCaseDescriptionEn); - assertEquals(newCaseDescriptionEn, detailsPage.getDescription()); - - // Change to language to German then change description - changeLanguage(3); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(caseNameGer); - detailsPage.changeCaseDescription(newCaseDescriptionGer); - assertEquals(newCaseDescriptionGer, detailsPage.getDescription()); - - // Change to English then verify description - changeLanguage(1); - detailsPage = casePage.openDetailsOfCaseHasName(caseNameEn); - assertEquals(newCaseDescriptionEn, detailsPage.getDescription()); - - // Change to German then verify description - changeLanguage(3); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(caseNameGer); - assertEquals(newCaseDescriptionGer, detailsPage.getDescription()); - } - - @Test - public void testUserWithoutPermissionCannotChangeCaseDescription() { - int caseIndex = 0; - newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - CaseDetailsPage detailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - assertFalse(detailsPage.isCaseDescriptionChangeComponentPresented(caseIndex)); - } - - public void changeLanguage(int index) { - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - userProfilePage.selectLanguage(index); - newDashboardPage = userProfilePage.save(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - var mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - } - - @After - public void resetlanguage() { - resetLanguageOfCurrentUser(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDetailsTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDetailsTest.java deleted file mode 100644 index 0394e68a404..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseDetailsTest.java +++ /dev/null @@ -1,453 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.lang.StringUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import ch.ivy.addon.portalkit.enums.PortalPermission; -import ch.ivy.addon.portalkit.util.ConfigurationJsonUtil; -import ch.ivyteam.ivy.workflow.task.TaskBusinessState; -import portal.guitest.common.BaseTest; -import portal.guitest.common.CaseState; -import portal.guitest.common.TestAccount; -import portal.guitest.common.TestRole; -import portal.guitest.common.Variable; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.AdditionalCaseDetailsPage; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.ExpressProcessPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NoteHistoryPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskTemplatePage; - -public class CaseDetailsTest extends BaseTest { - - private static final String RELATED_TASK_STATE_COLUMN = "related-task-state-column"; - private static final String RELATED_TASK_EXPIRY_COLUMN = "related-task-expiry-column"; - private NewDashboardPage newDashboardPage; - private CaseDetailsPage detailsPage; - - private static final String BUSINESS_CASE_MAP_LEAVE_REQUEST = "Business Case Map: Leave Request"; - private static final String LEAVE_REQUEST_CASE_NAME = "Leave Request"; - private static final String ORDER_PIZZA = "Order Pizza"; - private static final String GRANT_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL = - "portalKitTestHelper/14DE09882B540AD5/grantOnlyDelegateOwnTasksPermission.ivp"; - private static final String DENY_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL = - "portalKitTestHelper/14DE09882B540AD5/undoOnlyDelegateOwnTasksPermission.ivp"; - public static final String CUSTOM_CASE_WIDGET_NAME = "Create Event: Test custom case details"; - public static final String CREATE_EVENT_TEST_URL ="portal-developer-examples/17A2C6D73AB4186E/CreateEventTest.ivp"; - private static final String SICK_LEAVE_REQUEST_TASK ="Sick Leave Request"; - private static final String ANNUAL_LEAVE_REQUEST_TASK ="Annual Leave Request"; - - @Override - @Before - public void setup() { - super.setup(); - login(TestAccount.ADMIN_USER); - - newDashboardPage = new NewDashboardPage(); - grantSpecificPortalPermission(PortalPermission.TASK_CASE_ADD_NOTE); - } - - private void createTestingTask() { - redirectToRelativeLink(createTestingTasksUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(LEAVE_REQUEST_CASE_NAME); - } - - private void createTestingCaseContainTechnicalCases() { - redirectToRelativeLink(createCaseWithTechnicalCaseUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(ORDER_PIZZA); - } - - @Test - public void testDestroyCase() { - createTestingTask(); - assertEquals("Open", detailsPage.getCaseState()); - detailsPage.openActionMenu(); - detailsPage.onClickDestroyCase(); - detailsPage.confimDestruction(); - CaseWidgetPage casePage = new CaseWidgetPage(); - CaseState caseState = casePage.getCaseState(0); - assertEquals(CaseState.DESTROYED, caseState); - } - - @Test - public void testDisplayCaseProperties() { - createTestingTask(); - assertTrue(StringUtils.equalsIgnoreCase("Leave Request", detailsPage.getCaseCategory())); - assertTrue(StringUtils.isNotBlank(detailsPage.getCaseDuration())); - } - - @Test - public void testAddCaseNote() { - createTestingTask(); - assertEquals(1, detailsPage.getNumberOfHistory()); - detailsPage.addNote("Consider the remaining annual leaves before the approval"); - assertEquals(2, detailsPage.getNumberOfHistory()); - assertEquals("Consider the remaining annual leaves before the approval", detailsPage.getLatestHistoryContent()); - } - - @Test - public void testShowCaseDetail() { - createTestingCaseContainTechnicalCases(); - assertTrue(detailsPage.isGeneralInformationComponentPresented()); - assertTrue(detailsPage.isRelatedCasesComponentPresented()); - assertTrue(detailsPage.isRelatedTasksComponentPresented()); - assertTrue(detailsPage.isHistoryComponentPresented()); - assertTrue(detailsPage.isDocumentComponentPresented()); - } - - @Test - public void testShowBusinessCaseInTechnicalCase() { - redirectToRelativeLink(createTestingCaseMapUrl); - login(TestAccount.DEMO_USER); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openCaseDetailsFromActionMenuByCaseName(BUSINESS_CASE_MAP_LEAVE_REQUEST); - // check business case information is hidden in business case details - assertFalse(detailsPage.isBusinessCaseInformationSectionDisplayed()); - - // keep business case id - String originalBusinessCaseId = detailsPage.getCaseId(); - - // open related case detail - technical case detail - detailsPage.clickRelatedCaseActionButton(0); - CaseDetailsPage technicalCaseDetailsPage = detailsPage.openCasesOfCasePageViaDetailsAction(0); - WaitHelper.assertTrueWithWait(() -> "Case Details".equals(technicalCaseDetailsPage.getPageTitle())); - - // check business case information is displayed in technical case - WaitHelper.assertTrueWithWait(() -> detailsPage.isBusinessCaseInformationSectionDisplayed()); - - // open business case detail from technical case details - CaseDetailsPage businessCaseDetailsPage = technicalCaseDetailsPage.openBusinessCaseFromTechnicalCase(); - - // compare business case id - String businessCaseId = businessCaseDetailsPage.getCaseId(); - assertEquals(originalBusinessCaseId, businessCaseId); - } - - @Test - public void testRelatedTaskStartButtonStatus() { - createTestingTask(); - assertFalse(detailsPage.isRelatedTaskStartEnabled(ANNUAL_LEAVE_REQUEST_TASK)); - assertTrue(detailsPage.isRelatedTaskStartEnabled(SICK_LEAVE_REQUEST_TASK)); - } - - @Test - public void testRelatedTaskStartTask() { - createTestingTask(); - TaskTemplatePage taskTemplate = detailsPage.startRelatedTask(SICK_LEAVE_REQUEST_TASK); - assertEquals(SICK_LEAVE_REQUEST_TASK, taskTemplate.getTaskName()); - } - - @Test - public void testRelatedTaskReserveTask() { - createTestingTask(); - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - detailsPage.reserveTask(SICK_LEAVE_REQUEST_TASK); - assertTrue(detailsPage.isTaskState(SICK_LEAVE_REQUEST_TASK, TaskBusinessState.OPEN)); - - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - detailsPage.resetTask(SICK_LEAVE_REQUEST_TASK); - assertTrue(detailsPage.isTaskState(SICK_LEAVE_REQUEST_TASK, TaskBusinessState.OPEN)); - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - detailsPage.openRelatedTaskWorkflowEvents(detailsPage.getTaskRowIndex(SICK_LEAVE_REQUEST_TASK)); - - String dataFromWorkflowEvents = detailsPage.getEventTypeInWorkflowEvents(); - assertTrue(dataFromWorkflowEvents.contains("EVENT_ROLLBACK_TASK")); - assertTrue(dataFromWorkflowEvents.contains("EVENT_PARK_TASK")); - } - - @Test - public void testRelatedTaskDestroyTask() { - createTestingTask(); - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - Assert.assertTrue(detailsPage.isRelatedTaskDestroyEnabled(SICK_LEAVE_REQUEST_TASK)); - detailsPage.destroyTask(SICK_LEAVE_REQUEST_TASK); - detailsPage.confimRelatedTaskDestruction(); - assertTrue(detailsPage.isTaskState(SICK_LEAVE_REQUEST_TASK, TaskBusinessState.DESTROYED)); - } - - @Test - public void testRelatedTaskDelegateTask() { - createTestingTask(); - assertEquals(TestRole.EVERYBODY_ROLE, detailsPage.getResponsibleOfRelatedTaskAt(SICK_LEAVE_REQUEST_TASK)); - - detailsPage.openTaskDelegateDialog(SICK_LEAVE_REQUEST_TASK); - WaitHelper.assertTrueWithWait(() -> detailsPage.isDelegateTypeSelectAvailable()); - detailsPage.selectDelegateResponsible(TestAccount.HR_ROLE_USER.getFullName(), false); - assertEquals(TestAccount.HR_ROLE_USER.getFullName(), detailsPage.getResponsibleOfRelatedTaskAt(SICK_LEAVE_REQUEST_TASK)); - - detailsPage.openTaskDelegateDialog(SICK_LEAVE_REQUEST_TASK); - detailsPage.selectDelegateResponsible(TestRole.HR_ROLE, true); - assertEquals(TestRole.HR_ROLE, detailsPage.getResponsibleOfRelatedTaskAt(SICK_LEAVE_REQUEST_TASK)); - } - - @Test - public void testRelatedTaskDisplayDelegateButton() { - createTestingTask(); - redirectToRelativeLink(GRANT_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(LEAVE_REQUEST_CASE_NAME); - assertFalse(detailsPage.isTaskDelegateOptionDisable(SICK_LEAVE_REQUEST_TASK)); - assertTrue(detailsPage.isTaskDelegateOptionDisable(ANNUAL_LEAVE_REQUEST_TASK)); - redirectToRelativeLink(DENY_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL); - } - - @Test - public void testRelatedTaskOpenDetails() { - createTestingTask(); - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - int index = detailsPage.getTaskRowIndexFromDetailPage(SICK_LEAVE_REQUEST_TASK); - TaskDetailsPage taskDetailsPage = detailsPage.openTasksOfCasePageViaDetailsAction(index); - WaitHelper.assertTrueWithWait(() -> "Task Details".equals(taskDetailsPage.getPageTitle())); - } - - @Test - public void testRelatedCaseOpenDetails() { - createTestingCaseContainTechnicalCases(); - detailsPage.clickRelatedCaseActionButton(0); - CaseDetailsPage caseDetailsPage = detailsPage.openCasesOfCasePageViaDetailsAction(0); - WaitHelper.assertTrueWithWait(() -> "Case Details".equals(caseDetailsPage.getPageTitle())); - } - - @Test - public void testRelatedCaseOpenBusinessDetails() { - createTestingCaseContainTechnicalCases(); - detailsPage.clickRelatedCaseActionButton(0); - AdditionalCaseDetailsPage caseDetailsPage = detailsPage.openRelatedCaseBusinessDetail(0); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> caseDetailsPage.countBrowserTab() > 1); - caseDetailsPage.switchLastBrowserTab(); - AdditionalCaseDetailsPage additionalCaseDetailsPage = new AdditionalCaseDetailsPage(); - WaitHelper.assertTrueWithWait(() -> "Business Details".equals(additionalCaseDetailsPage.getPageTitle())); - } - - @Test - public void testRelatedCaseSideSteps() { - redirectToRelativeLink(createTestingCaseMapUrl); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(BUSINESS_CASE_MAP_LEAVE_REQUEST); - assertEquals(1, detailsPage.countRelatedCases()); - detailsPage.clickRelatedCaseActionButton(0); - detailsPage.clickRelatedCaseSubmitLeaveReason(0); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(BUSINESS_CASE_MAP_LEAVE_REQUEST); - assertEquals(2, detailsPage.countRelatedCases()); - detailsPage.clickRelatedCaseActionButton(0); - detailsPage.clickRelatedCaseUploadAdditionalDocument(0); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(BUSINESS_CASE_MAP_LEAVE_REQUEST); - assertEquals(3, detailsPage.countRelatedCases()); - } - - @Test - public void testRelatedTaskOpenWorkflowEvents() { - createTestingTask(); - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - int index = detailsPage.getTaskRowIndexFromDetailPage(SICK_LEAVE_REQUEST_TASK); - detailsPage.openRelatedTaskWorkflowEvents(index); - assertTrue(detailsPage.isRelatedTaskWorkflowEventsOpened()); - } - - @Test - public void testRelatedTaskAddAdHocTask() { - createTestingTask(); - detailsPage.clickRelatedTaskActionButton(SICK_LEAVE_REQUEST_TASK); - ExpressProcessPage expressProcessPage = detailsPage.addAdHocTask(detailsPage.getTaskRowIndex(SICK_LEAVE_REQUEST_TASK)); - assertTrue(expressProcessPage.getProcessName().endsWith(SICK_LEAVE_REQUEST_TASK)); - } - - @Test - public void testRelatedTaskExportToExcel() { - createTestingTask(); - detailsPage.clickExportToExcelLink("related-task-export-to-excel", "related-task-status-dialog"); - assertTrue(detailsPage.isDownloadCompleted("related-task-status-dialog")); - } - - @Test - public void testRelatedCaseExportToExcel() { - createTestingCaseContainTechnicalCases(); - detailsPage.clickExportToExcelLink("related-case-export-to-excel", "related-case-status-dialog"); - assertTrue(detailsPage.isDownloadCompleted("related-case-status-dialog")); - } - - @Test - public void testRelatedTaskEnableAndDisableColumns() { - createTestingTask(); - assertTrue(detailsPage.isRelatedTaskListColumnExist(RELATED_TASK_EXPIRY_COLUMN)); - assertTrue(detailsPage.isRelatedTaskListColumnExist(RELATED_TASK_STATE_COLUMN)); - detailsPage.clickRelatedTaskColumnsButton(); - detailsPage.clickRelatedTaskDefaultCheckbox(); - detailsPage.clickRelatedTaskColumnCheckbox(6); - detailsPage.clickRelatedTaskApplyButton(); - WaitHelper.assertTrueWithWait(() -> !detailsPage.isRelatedTaskListColumnExist(RELATED_TASK_EXPIRY_COLUMN)); - WaitHelper.assertTrueWithWait(() -> detailsPage.isRelatedTaskListColumnExist(RELATED_TASK_STATE_COLUMN)); - detailsPage.clickRelatedTaskColumnsButton(); - detailsPage.clickRelatedTaskColumnCheckbox(6); - detailsPage.clickRelatedTaskColumnCheckbox(8); - detailsPage.clickRelatedTaskApplyButton(); - WaitHelper.assertTrueWithWait(() -> detailsPage.isRelatedTaskListColumnExist(RELATED_TASK_EXPIRY_COLUMN)); - WaitHelper.assertTrueWithWait(() -> !detailsPage.isRelatedTaskListColumnExist(RELATED_TASK_STATE_COLUMN)); - } - - @Test - public void testHistoryAuthorIsUserFullName() { - createTestingTask(); - detailsPage.addNote("Sample case note"); - assertEquals(TestAccount.ADMIN_USER.getFullName(), detailsPage.getHistoryAuthor()); - } - - @Test - public void testHistoryShowDoneTasks() { - redirectToRelativeLink(createTestingCaseMapUrl); - login(TestAccount.DEMO_USER); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openCaseDetailsFromActionMenuByCaseName(BUSINESS_CASE_MAP_LEAVE_REQUEST); - assertTrue(detailsPage.checkDoneTasksOfHistory()); - - int relatedDoneTasks = detailsPage.countRelatedDoneTasks(); - detailsPage.showNoteHistory(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> detailsPage.countBrowserTab() > 1); - detailsPage.switchLastBrowserTab(); - NoteHistoryPage caseHistoryPage = new NoteHistoryPage(); - assertEquals(relatedDoneTasks, caseHistoryPage.countDoneTasks()); - } - - @Test - public void testOpenViewNoteDialog() { - createTestingTask(); - detailsPage.addNote("Consider the remaining annual leaves before the approval"); - detailsPage.clickViewNote(); - assertTrue(detailsPage.isViewNoteDialogPresented()); - } - - @Test - public void testDragDropWidgets() { - createTestingTask(); - detailsPage.switchToEditMode(); - detailsPage.waitForSaveButtonDisplayed(); - detailsPage.drapAndDropWidgets("information", "document"); - detailsPage.drapAndDropWidgets("document", "information"); - detailsPage.saveAndSwitchToViewMode(); - detailsPage.switchToEditMode(); - detailsPage.waitForResetButtonDisplayed(); - detailsPage.resetToDefault(); - detailsPage.confirmResetToDefault(); - detailsPage.saveAndSwitchToViewMode(); - } - - @Test - public void testCustomWidgetsInCaseDetails() throws IOException { - redirectToRelativeLink(CREATE_EVENT_TEST_URL); - - setupCaseDetailsWithIFrameProcess(); - assumeTrue("iframe CustomWidget is displayed", detailsPage.iframeCustomWidgetIsDisplayed()); - String processLink = detailsPage.getProcessLinkInCustomIFrameWidget(); - assertTrue(processLink.contains("portal-developer-examples/17A2C6D73AB4186E/startReview.ivp")); - - setupCaseDetailsWithIFrameURL(); - String url = detailsPage.getIFrameURLOfCustomWidget(); - assertTrue(url.contains("www.axonivy.com")); - - setupCaseDetailsWith2Panels(); - assertTrue(detailsPage.isCustomMiddlePanelDisplay()); - } - - public void setupCaseDetailsWith2Panels() throws IOException { - ConfigurationJsonUtil.updateJSONSetting("custom-case-details-with-panel.json", Variable.CASE_DETAIL); - detailsPage = goToCaseList().openDetailsOfCaseHasName(CUSTOM_CASE_WIDGET_NAME); - } - - public void setupCaseDetailsWithIFrameURL() throws IOException { - ConfigurationJsonUtil.updateJSONSetting("custom-case-details-with-url.json", Variable.CASE_DETAIL); - detailsPage = goToCaseList().openDetailsOfCaseHasName(CUSTOM_CASE_WIDGET_NAME); - } - - public void setupCaseDetailsWithIFrameProcess() throws IOException { - ConfigurationJsonUtil.updateJSONSetting("custom-case-details.json", Variable.CASE_DETAIL); - detailsPage = goToCaseList().openDetailsOfCaseHasName(CUSTOM_CASE_WIDGET_NAME); - } - - public CaseWidgetPage goToCaseList() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - return casePage; - } - - @After - public void teardown() { - denySpecificPortalPermission(PortalPermission.TASK_CASE_ADD_NOTE); - } - - @Test - public void testShowRelatedCaseLinkInNote() { - createTestingCaseContainTechnicalCases(); - assertEquals(1, detailsPage.getNumberOfHistory()); - detailsPage.addNote("This is note on business case"); - assertEquals(2, detailsPage.getNumberOfHistory()); - assertEquals("This is note on business case", detailsPage.getLatestHistoryContent()); - detailsPage.clickRelatedCaseActionButton(0); - var relatedCaseDetailsPage = detailsPage.openCasesOfCasePageViaDetailsAction(0); - WaitHelper.assertTrueWithWait(() -> "Case Details".equals(relatedCaseDetailsPage.getPageTitle())); - relatedCaseDetailsPage.addNote("The first note of sub-case"); - relatedCaseDetailsPage.addNote("The second note of sub-case"); - var subCaseId = relatedCaseDetailsPage.getCaseId(); - var caseName = relatedCaseDetailsPage.getCaseName(); - assertEquals(2, relatedCaseDetailsPage.getNumberOfHistory()); - assertEquals(0, relatedCaseDetailsPage.getNumberOfHistoryForRelatedCaseLink()); - detailsPage = relatedCaseDetailsPage.openBusinessCaseFromTechnicalCase(); - assertEquals(4, detailsPage.getNumberOfHistory()); - assertEquals(2, detailsPage.getNumberOfHistoryForRelatedCaseLink()); - var relaledCaseName = detailsPage.getContentOfHistoryTableRelatedCaseColumn(0); - assertTrue(relaledCaseName.startsWith("#")); - assertTrue(relaledCaseName.contains(subCaseId)); - assertTrue(relaledCaseName.contains(caseName)); - } - - @Test - public void testShowRelatedCaseInfoByConfigInCaseHistory() { - updateGlobalVariable(Variable.HIDE_RELATED_CASE_INFO_FROM_HISTORY.getKey(), "false"); - createTestingCaseContainTechnicalCases(); - executeDecorateJs("window.scrollTo(0, document.body.scrollHeight)"); - assertTrue("Related Case checkbox is not display", detailsPage.isShowRelatedCaseCheckbox()); - detailsPage.clickOnRelatedCaseCheckbox(true); - assertTrue("Related Case column is not display", detailsPage.isRelatedCaseInfoColumnIsDisplay()); - detailsPage.clickOnRelatedCaseCheckbox(false); - assertFalse("Related Case column is display", detailsPage.isRelatedCaseInfoColumnIsDisplay()); - updateGlobalVariable(Variable.HIDE_RELATED_CASE_INFO_FROM_HISTORY.getKey(), "true"); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(ORDER_PIZZA); - assertFalse("Related Case checkbox is display", detailsPage.isShowRelatedCaseCheckbox()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseFilterTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseFilterTest.java deleted file mode 100644 index 786cf5233ff..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseFilterTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.ENABLE_CASE_OWNER; - -import org.apache.commons.codec.binary.StringUtils; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; - -public class CaseFilterTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - } - - @Test - public void testCaseOwnerFilter() { - updatePortalSetting(ENABLE_CASE_OWNER.getKey(), "true"); - redirectToRelativeLink(userIsOwnerUrl); - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - - casePage.openAdvancedFilter("Owner", "owner"); - casePage.filterByOwner("Demo"); - assertEquals(1, casePage.getNumberOfCases()); - updatePortalSetting(ENABLE_CASE_OWNER.getKey(), "false"); - } - - @Test - public void testCaseAdvancedFilter() { - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - - casePage.openAdvancedFilter("Description", "description"); - casePage.filterByDescription("random text"); - WaitHelper.assertTrueWithWait(() -> { - return casePage.getNumberOfCases() == 0; - }); - - casePage.filterByDescription("Leave Request Description"); - WaitHelper.assertTrueWithWait(() -> { - return casePage.getNumberOfCases() == 1; - }); - } - - @Test - public void testSaveFilter() { - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - - casePage.openAdvancedFilter("Description", "description"); - casePage.filterByDescription("leave"); - String filterName = "leave"; - casePage.saveFilter(filterName); - - mainMenuPage.selectTaskMenu(); - casePage = mainMenuPage.openCaseList(); - assertEquals(filterName, casePage.getFilterName().toLowerCase()); - } - - @Test - public void testCategory() { - MainMenuPage mainMenuPage = new MainMenuPage(); - CaseWidgetPage casePage = mainMenuPage.openCaseList(); - - String caseCategoryId = "case-category"; - casePage.openAdvancedFilter("Case category", caseCategoryId); - assertEquals("Case category: All", casePage.getFilterValue(caseCategoryId + "-filter")); - casePage.openCategoryFilter(); - assertTrue(casePage.isAllCategoriesSelected()); - - casePage.toggleNoCategory(); - assertTrue(casePage.isAllCategoriesUnselected()); - - casePage.applyCategoryFilter(); - assertFalse(StringUtils.equals("Case category: All", casePage.getFilterValue(caseCategoryId + "-filter"))); - } - - @Test - public void testRemoveResponsibleAndSwitchFilter() { - // Prepare 2 filter - String filterResponsible = "Responsible"; - String filterMaternity = "Maternity"; - - MainMenuPage mainMenuPage = new MainMenuPage(); - CaseWidgetPage casePage = mainMenuPage.openCaseList(); - casePage.openAdvancedFilter("Description", "description"); - casePage.filterByDescription(filterMaternity); - casePage.saveFilter(filterMaternity); - - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - - casePage = mainMenuPage.selectCaseMenu(); - casePage.openAdvancedFilter("Creator", "creator"); - casePage.filterByCreator("Demo"); - casePage.saveFilter(filterResponsible); - // Switch filter and remove responsible - casePage.openSavedFilters(filterMaternity); - casePage.openSavedFilters(filterResponsible); - casePage.removeResponsibleFilter(); - casePage.openSavedFilters(filterMaternity); - casePage.openSavedFilters(filterResponsible); - - assertTrue(casePage.getCreator().contains("Portal Demo User")); - } - - @Test - public void testDefaultFilter() { - MainMenuPage mainMenuPage = new MainMenuPage(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - assertTrue(casePage.getFilterName().contains("Default filter")); - } - - @Test - public void testNoSelectionWhenChangeFilter() { - String filterMaternity = "Maternity"; - MainMenuPage mainMenuPage = new MainMenuPage(); - CaseWidgetPage casePage = mainMenuPage.openCaseList(); - casePage.openAdvancedFilter("Description", "description"); - casePage.filterByDescription(filterMaternity); - casePage.saveFilter(filterMaternity); - casePage.openAdvancedFilter("Creator", "creator"); - casePage.filterByCreator("Demo"); - - assertTrue(casePage.getFilterName().contains("No Selection")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseOwnerTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseOwnerTest.java deleted file mode 100644 index 72473fea069..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseOwnerTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.ENABLE_CASE_OWNER; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; - -public class CaseOwnerTest extends BaseTest { - - private static final String USER_IS_OWNER_URL = "internalSupport/16A68510A341BE6E/userIsOwner.ivp"; - private static final String ROLE_IS_OWNER_URL = "internalSupport/16A68510A341BE6E/roleIsOwner.ivp"; - - private NewDashboardPage newDashboardPage; - private MainMenuPage mainMenuPage; - private CaseWidgetPage casePage; - - @Override - @Before - public void setup() { - super.setup(); - updatePortalSetting(ENABLE_CASE_OWNER.getKey(), "true"); - } - - @After - public void destroy() { - updatePortalSetting(ENABLE_CASE_OWNER.getKey(), "false"); - } - - @Test - public void testUserIsOwner() { - redirectToRelativeLink(USER_IS_OWNER_URL); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertTrue(casePage.isCaseDisplayed("demo user is owner")); - } - - @Test - public void testRoleIsOwner() { - redirectToRelativeLink(ROLE_IS_OWNER_URL); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - login(TestAccount.CASE_OWNER_USER); - - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertTrue(casePage.isCaseDisplayed("Test role is owner")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseWidgetTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseWidgetTest.java deleted file mode 100644 index e426f1e23e9..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/CaseWidgetTest.java +++ /dev/null @@ -1,307 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.DISABLE_CASE_COUNT; - -import java.util.concurrent.TimeUnit; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.TimeoutException; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.CaseState; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.AdditionalCaseDetailsPage; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserProfilePage; - -public class CaseWidgetTest extends BaseTest { - - private static final String INVESTMENT_REQUEST_CUSTOMIZATION_CASE_DETAILS_PAGE_CASE_NAME = "Create Investment"; - private static final String LEAVE_REQUEST_DEFAULT_CASE_DETAILS_PAGE_CASE_NAME = "Leave Request for Default Additional Case Details"; - private static final String LEAVE_REQUEST_CASE_NAME = "Leave Request"; - private static final String ORDER_PIZZA = "Order Pizza"; - private static final String CREATED_COLUMN_HEADER = "Created"; - private static final String STATE_COLUMN_HEADER = "State"; - private static final String RELATED_CASE_STATE_COLUMN = "state-column"; - private static final String RELATED_CASE_CREATED_COLUMN = "created-column"; - - private NewDashboardPage newDashboardPage; - private MainMenuPage mainMenuPage; - private CaseWidgetPage casePage; - private CaseDetailsPage caseDetailsPage; - private AdditionalCaseDetailsPage additionalCaseDetailsPage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - } - - @Test - public void testHideCase() { - redirectToRelativeLink(hideCaseUrl); - initNewDashboardPage(TestAccount.ADMIN_USER); - - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Report and hide case", 2); - taskWidgetPage.startTaskWithoutUI(1); - newDashboardPage = new NewDashboardPage(); - - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertFalse(casePage.isCaseDisplayed("Repair Computer")); - } - - @SuppressWarnings("deprecation") - @Test - public void testDestroyCaseWithPermission() { - initNewDashboardPage(TestAccount.ADMIN_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - casePage.clickDestroyButton(); - casePage.confimDestruction(); - casePage.waitAjaxIndicatorDisappear(); - CaseState caseState = casePage.getCaseState(0); - assertEquals(CaseState.DESTROYED, caseState); - - } - - @Test - public void testDestroyCaseWithoutPermission() { - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertFalse(casePage.isDestroyButtonVisible()); - } - - @Test - public void testOpenRelatedTasksOfCase() { - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - caseDetailsPage = casePage.openDetailsOfCaseHasName(LEAVE_REQUEST_CASE_NAME); - assertEquals(4, caseDetailsPage.countRelatedTasks()); - } - - @Test - public void testOpenRelatedCasesOfCase() { - redirectToRelativeLink(createCaseWithTechnicalCaseUrl); - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - caseDetailsPage = casePage.openDetailsOfCaseHasName(ORDER_PIZZA); - assertEquals(1, caseDetailsPage.countRelatedCases()); - } - - @Test - public void testOpenAdditionalCaseDetailsPage() throws Exception { - openAdditionalCaseDetailsPage(createTestingCaseUrlForDefaultAdditionalCaseDetails, LEAVE_REQUEST_DEFAULT_CASE_DETAILS_PAGE_CASE_NAME); - validateAdditionalCaseDetailsPage(13, "Customer name"); - } - - @Test - public void testOpenCustomizationAdditionalCaseDetailsPage() throws Exception { - openAdditionalCaseDetailsPage(createTestingCaseUrlForCustomizationAdditionalCaseDetails, INVESTMENT_REQUEST_CUSTOMIZATION_CASE_DETAILS_PAGE_CASE_NAME); - validateAdditionalCaseDetailsPage(4, "Apartment A"); - } - - @Test - public void testEnableAndDisableColumnsInCaseWidget() { - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertTrue(casePage.isCaseListColumnExist(CREATED_COLUMN_HEADER)); - assertTrue(casePage.isCaseListColumnExist(STATE_COLUMN_HEADER)); - casePage.clickColumnsButton(); - casePage.clickDefaultCheckbox(); - casePage.clickColumnCheckbox(4); - casePage.clickApplyButton(); - WaitHelper.assertTrueWithWait(() -> !casePage.isCaseListColumnExist(CREATED_COLUMN_HEADER)); - WaitHelper.assertTrueWithWait(() -> casePage.isCaseListColumnExist(STATE_COLUMN_HEADER)); - casePage.clickColumnsButton(); - casePage.clickColumnCheckbox(4); - casePage.clickColumnCheckbox(6); - casePage.clickApplyButton(); - WaitHelper.assertTrueWithWait(() -> casePage.isCaseListColumnExist(CREATED_COLUMN_HEADER)); - WaitHelper.assertTrueWithWait(() -> !casePage.isCaseListColumnExist(STATE_COLUMN_HEADER)); - } - - private void openAdditionalCaseDetailsPage(String initDataUrl, String caseName){ - redirectToRelativeLink(initDataUrl); - initNewDashboardPage(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - mainMenuPage = newDashboardPage.openMainMenu(); - additionalCaseDetailsPage = new AdditionalCaseDetailsPage(); - casePage = mainMenuPage.selectCaseMenu(); - caseDetailsPage = casePage.openDetailsOfCaseHasName(caseName); - caseDetailsPage.openActionMenu(); - caseDetailsPage.openAdditionalCaseDetailsPage(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - } - - private void validateAdditionalCaseDetailsPage(int expectedNumberOfFields, String expectedFirstFieldValue){ - int numberOfFields; - try { - numberOfFields = additionalCaseDetailsPage.countFields(); - } catch (TimeoutException e) { // sometimes session is destroyed (don't know reason why!!!) so we cannot reach the page - System.out.println("Stop testOpenCustomizationAdditionalCaseDetailsPage test here because session is destroyed"); - return ; - } - assertEquals(expectedNumberOfFields, numberOfFields); - assertEquals(expectedFirstFieldValue, additionalCaseDetailsPage.getAdditionalFieldContentOfFirstRow()); - } - - private void initNewDashboardPage(TestAccount account) { - login(account); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testShowCaseCount() { - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - casePage.waitUntilCaseCountDifferentThanZero(); - assertEquals(1, casePage.getCaseCount().intValue()); - } - - @Test - public void testDisableCaseCount() { - updatePortalSetting(DISABLE_CASE_COUNT.getKey(), "true"); - initNewDashboardPage(TestAccount.ADMIN_USER); - - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertEquals("Case count is not disabled", null, casePage.getCaseCount()); - } - - @Test - public void testBreadCrumb() { - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - assertEquals("Cases (1)", casePage.getTextOfCurrentBreadcrumb()); - newDashboardPage = casePage.goToHomeFromBreadcrumb(); - assertTrue(newDashboardPage.isDisplayed()); - } - - @Test - public void testBreadCrumbInCaseDetail() { - initNewDashboardPage(TestAccount.DEMO_USER); - mainMenuPage = newDashboardPage.openMainMenu(); - casePage = mainMenuPage.selectCaseMenu(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - assertEquals("Case: Leave Request", caseDetailsPage.getTextOfCurrentBreadcrumb()); - - caseDetailsPage.clickCaseListBreadCrumb(); - casePage = new CaseWidgetPage(); - assertTrue(casePage.isDisplayed()); - - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - newDashboardPage = caseDetailsPage.goToHomeFromBreadcrumb(); - assertTrue(newDashboardPage.isDisplayed()); - } - - @Test - public void testChangeCaseSortingOptions() { - redirectToRelativeLink(create12CasesWithCategoryUrl); - - NewDashboardPage newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - - // Change sorting options - userProfilePage.selectCaseSortField("Name"); - userProfilePage.selectCaseSortDirection("Sort ascending"); - newDashboardPage = userProfilePage.save(); - - // Check result - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - assertEquals("Create 12 Cases with category", caseWidgetPage.getCaseNameAt(0)); - assertEquals("TestCase", caseWidgetPage.getCaseNameAt(13)); - - // Change sorting options - userProfilePage = caseWidgetPage.openMyProfilePage(); - userProfilePage.selectCaseSortField("State"); - userProfilePage.selectCaseSortDirection("Sort descending"); - newDashboardPage = userProfilePage.save(); - - // Check result - caseWidgetPage = newDashboardPage.openCaseList(); - assertEquals(CaseState.DONE, caseWidgetPage.getCaseState(0)); - } - - @Test - public void testExportToExcel() { - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - - caseWidgetPage.clickExportToExcelLink(); - - assertTrue(caseWidgetPage.isDownloadCompleted()); - } - - @Test - public void testStickySortCaseList() { - redirectToRelativeLink(create12CasesWithCategoryUrl); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - caseWidgetPage.sortCaseListByColumn("case-widget:case-list-header:created-date-column-header:created-date-column-header"); - caseWidgetPage.clickOnLogo(); - newDashboardPage = new NewDashboardPage(); - caseWidgetPage = newDashboardPage.openCaseList(); - String selectedSortColumn = caseWidgetPage.getSelectedSortColumn(); - assertTrue(StringUtils.equalsIgnoreCase("Created", selectedSortColumn)); - String caseName = caseWidgetPage.getCaseNameAt(0); - assertTrue(StringUtils.equalsIgnoreCase("Leave Request", caseName)); - // Change sorting options - UserProfilePage userProfilePage = caseWidgetPage.openMyProfilePage(); - userProfilePage.selectCaseSortField("State"); - userProfilePage.selectCaseSortDirection("Sort descending"); - newDashboardPage = userProfilePage.save(); - - // Check result - caseWidgetPage = newDashboardPage.openCaseList(); - selectedSortColumn = caseWidgetPage.getSelectedSortColumn(); - assertTrue(StringUtils.equalsIgnoreCase("State", selectedSortColumn)); - assertEquals(CaseState.DONE, caseWidgetPage.getCaseState(0)); - } - - @Test - public void testRelatedCaseEnableAndDisableColumns() { - redirectToRelativeLink(createCaseWithTechnicalCaseUrl); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - CaseWidgetPage casePage = newDashboardPage.openCaseList(); - CaseDetailsPage detailsPage = casePage.openDetailsOfCaseHasName(ORDER_PIZZA); - assertTrue(detailsPage.isRelatedCaseListColumnExist(RELATED_CASE_CREATED_COLUMN)); - assertTrue(detailsPage.isRelatedCaseListColumnExist(RELATED_CASE_STATE_COLUMN)); - detailsPage.clickRelatedCaseColumnsButton(); - detailsPage.clickRelatedCaseDefaultCheckbox(); - detailsPage.clickRelatedCaseColumnCheckbox(4); - detailsPage.clickRelatedCaseApplyButton(); - WaitHelper.assertTrueWithWait(() -> !detailsPage.isRelatedCaseListColumnExist(RELATED_CASE_CREATED_COLUMN)); - WaitHelper.assertTrueWithWait(() -> detailsPage.isRelatedCaseListColumnExist(RELATED_CASE_STATE_COLUMN)); - detailsPage.clickRelatedCaseColumnsButton(); - detailsPage.clickRelatedCaseColumnCheckbox(4); - detailsPage.clickRelatedCaseColumnCheckbox(6); - detailsPage.clickRelatedCaseApplyButton(); - WaitHelper.assertTrueWithWait(() -> detailsPage.isRelatedCaseListColumnExist(RELATED_CASE_CREATED_COLUMN)); - WaitHelper.assertTrueWithWait(() -> !detailsPage.isRelatedCaseListColumnExist(RELATED_CASE_STATE_COLUMN)); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTest.java deleted file mode 100644 index 52b136e88d2..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTest.java +++ /dev/null @@ -1,224 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.ENABLE_GROUP_CHAT; -import static portal.guitest.common.Variable.ENABLE_PRIVATE_CHAT; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.Sleeper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.ChatPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class ChatTest extends BaseTest { - private static final String ADMIN1_2 = "admin1-2"; - private static final String ADMIN1_1 = "admin1-1"; - private static final String DEMO1_2 = "demo1-2"; - private static final String DEMO1_1 = "demo1-1"; - private static final String ENABLE_PRIVATE_CHAT_SETTING = ENABLE_PRIVATE_CHAT.getKey(); - private static final String ENABLE_GROUP_CHAT_SETTING = ENABLE_GROUP_CHAT.getKey(); - private static final String CHAT_MESSAGE_USER_DEMO = "Hi i'm demo user"; - private static final String CHAT_MESSAGE_USER_ADMIN = "Hi i'm admin user"; - ExpressResponsible chatUser1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible chatGroup1 = new ExpressResponsible("Human resources department", true); - ExpressResponsible chatGroupEveryBody = new ExpressResponsible("Everybody", true); - - @Override - @Before - public void setup() { - super.setup(); - } - - @Test - public void chatAddGroup() { - ChatPage chatPage = enableChatGroup(); - createChatGroup(TestAccount.DEMO_USER); - joinChatGroupWhichAlreadyHadChatGroup(TestAccount.ADMIN_USER); - chatMessageInGroup(TestAccount.DEMO_USER, CHAT_MESSAGE_USER_DEMO); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPage2 = chatMessageInGroup(TestAccount.ADMIN_USER, CHAT_MESSAGE_USER_ADMIN); - - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - createChatGroup(TestAccount.GUEST_USER, chatUser1, chatGroupEveryBody); - - - assertEquals(2, chatPage2.refreshAndCountGroupChat()); - assertEquals(2, chatPage.refreshAndCountGroupChat()); - } - - @Test - public void chatGroupOnTwoInstanceOfBrowser() { - ChatPage chatPage = enableChatGroup(); - createChatGroup(TestAccount.DEMO_USER); - joinChatGroupWhichAlreadyHadChatGroup(TestAccount.ADMIN_USER); - chatMessageInGroup(TestAccount.DEMO_USER, CHAT_MESSAGE_USER_DEMO); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPage2 = chatMessageInGroup(TestAccount.ADMIN_USER, CHAT_MESSAGE_USER_ADMIN); - chatPage2.closeChatMessageList(); - chatPage.sendMessage("from 1 to 2"); - assertChatNotification(chatPage2, true); - chatPage2.openFirstGroupChat(); - chatPage2.sendMessage("from 2 to 1"); - assertContainMessage(chatPage, "from 2 to 1"); - assertContainMessage(chatPage2, "from 1 to 2"); - } - - @Test - public void chatDisplay() { - enableChatGroup(); - assertTrue("Chat Shown", new NewDashboardPage().isChatDisplayed()); - } - - @Test - public void chatPrivate() { - ChatPage chatPage = enableChatPrivate(); - chatPage.selectChatUser("demo"); - chatPage.sendMessage(CHAT_MESSAGE_USER_ADMIN); - - login(TestAccount.DEMO_USER); - new NewDashboardPage().getChat(); - chatPage.selectChatUser("admin"); - chatPage.sendMessage(CHAT_MESSAGE_USER_DEMO); - } - - @Test - public void joinChatGroupAlreadyCreated() { - ChatPage chatPage = enableChatGroup(); - createChatGroup(TestAccount.DEMO_USER); - joinChatGroupWhichAlreadyHadChatGroup(TestAccount.ADMIN_USER); - chatMessageInGroup(TestAccount.DEMO_USER, CHAT_MESSAGE_USER_DEMO); - chatMessageInGroup(TestAccount.ADMIN_USER, CHAT_MESSAGE_USER_ADMIN); - - assertContainMessage(chatPage, CHAT_MESSAGE_USER_DEMO); - assertContainMessage(chatPage, CHAT_MESSAGE_USER_ADMIN); - - login(TestAccount.DEMO_USER); - WaitHelper.assertTrueWithWait(() -> new NewDashboardPage().getChat().isNotificationContactChat()); - } - - @Test - public void chatGroupMultiTabs() { - enableChatGroup(); - createChatGroup(TestAccount.DEMO_USER); - ChatPage chatPageDemo1 = new ChatPage(); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPageDemo2 = openChatGroup(TestAccount.DEMO_USER); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - joinChatGroupWhichAlreadyHadChatGroup(TestAccount.ADMIN_USER); - ChatPage chatPageAdmin1 = new ChatPage(); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPageAdmin2 = openChatGroup(TestAccount.ADMIN_USER); - chatPageAdmin1.closeChatMessageList(); - chatPageAdmin2.closeChatMessageList(); - - // demo1, demo2 with group opened, admin1, admin2 with group closed, demo1 sends message - chatPageDemo1.sendMessage(DEMO1_1); - assertChatNotification(chatPageDemo2, false); - assertContainMessage(chatPageDemo2, DEMO1_1); - assertChatNotification(chatPageAdmin1, true); - assertChatNotification(chatPageAdmin2, true); - // admin1 opens group - chatPageAdmin1.openFirstGroupChat(); - assertContainMessage(chatPageAdmin1, DEMO1_1); - assertChatNotification(chatPageAdmin2, false); - - // demo1, demo2, admin1 with group opened, admin2 with group closed, demo1 sends message - chatPageDemo1.sendMessage(DEMO1_2); - assertContainMessage(chatPageAdmin1, DEMO1_2); - assertChatNotification(chatPageAdmin2, false); - - // demo1, demo2, admin2 with group opened, admin2 with group closed, admin1 sends message - chatPageAdmin1.sendMessage(ADMIN1_1); - assertChatNotification(chatPageAdmin2, false); - assertContainMessage(chatPageDemo1, ADMIN1_1); - assertContainMessage(chatPageDemo2, ADMIN1_1); - - // demo1, demo2, demo3, demo4, admin2 with group opened, admin2 with group closed, admin1 sends message - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPageDemo3 = openChatGroup(TestAccount.DEMO_USER); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPageDemo4 = openChatGroup(TestAccount.DEMO_USER); - chatPageAdmin1.sendMessage(ADMIN1_2); - //TODO need to be fixed - Workaround for wait message render - Sleeper.sleep(3000); - assertContainMessage(chatPageDemo1, ADMIN1_2); - assertContainMessage(chatPageDemo2, ADMIN1_2); - assertContainMessage(chatPageDemo3, ADMIN1_2); - assertContainMessage(chatPageDemo4, ADMIN1_2); - } - - private void assertContainMessage(ChatPage chatPage, String message) { - WaitHelper.assertTrueWithWait(() -> chatPage.getAllMessagesChatLog().contains(message)); - } - - private void assertChatNotification(ChatPage chatPage, boolean hasNotification) { - WaitHelper.assertTrueWithWait(() -> hasNotification == chatPage.isNotificationBadgeChat()); - WaitHelper.assertTrueWithWait(() -> hasNotification == chatPage.isNotificationContactChat()); - } - - private ChatPage chatMessageInGroup(TestAccount chatUser, String chatMessage) { - ChatPage chatPage = openChatGroup(chatUser); - chatPage.sendMessage(chatMessage); - return chatPage; - } - - private ChatPage openChatGroup(TestAccount chatUser) { - login(chatUser); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPage = new NewDashboardPage().getChat(); - chatPage.openFirstGroupChat(); - return chatPage; - } - - private ChatPage createChatGroup(TestAccount creatorChatGroup, ExpressResponsible ...participants) { - redirectToRelativeLink(createTestingCaseUrlForDefaultAdditionalCaseDetails); - login(creatorChatGroup); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - ChatPage chatPage = new NewDashboardPage().getChat(); - // Create chat group via task - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - taskTemplatePage.clickTaskActionMenu(); - taskTemplatePage.clickChatGroup(); - if (participants.length != 0) { - chatPage.addUserToChatGroup(Arrays.asList(participants)); - } - taskTemplatePage.clickCreateGroupChatBtn(); - return chatPage; - } - - private void joinChatGroupWhichAlreadyHadChatGroup(TestAccount userJoined) { - login(userJoined); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Sick Leave Request Default Case Details Page"); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - taskTemplatePage.clickTaskActionMenu(); - taskTemplatePage.clickChatGroup(); - taskTemplatePage.joinProcessChatAlreadyCreated(); - } - - private ChatPage enableChatGroup() { - updatePortalSetting(ENABLE_GROUP_CHAT_SETTING, "true"); - login(TestAccount.ADMIN_USER); - return new ChatPage(); - } - - private ChatPage enableChatPrivate() { - updatePortalSetting(ENABLE_PRIVATE_CHAT_SETTING, "true"); - login(TestAccount.ADMIN_USER); - new NewDashboardPage().getChat(); - return new ChatPage(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTestKillBrowsersTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTestKillBrowsersTest.java deleted file mode 100644 index d71181b18f6..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ChatTestKillBrowsersTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package portal.guitest.test; - -import java.io.IOException; - -import org.junit.Test; - -import portal.guitest.common.Sleeper; - -/** - * This is a work around to kill all browsers after ChatTest. - * If killing browsers in @AfterClass of ChatTest first then in ScreenshotFailedTestRule shutdown the browser, shutting down the browser could take 3 hours to finish. - */ -public class ChatTestKillBrowsersTest { - - - @Test - public void killBrowsers() { - try { - System.out.println("Kill all open browsers"); - Runtime.getRuntime().exec("taskkill /F /IM iexplore.exe"); - Runtime.getRuntime().exec("taskkill /F /IM firefox.exe"); - Sleeper.sleep(5000); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ClientSideTimeoutTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ClientSideTimeoutTest.java deleted file mode 100644 index 46e65f8e586..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ClientSideTimeoutTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.NewDashboardPage; - -public class ClientSideTimeoutTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - setupWithAlternativeLinkAndAccount(NewDashboardPage.PORTAL_HOME_PAGE_URL, TestAccount.ADMIN_USER); - } - - @Test - public void testShowWarningDialog(){ - AdminSettingsPage adminSettingPage = setupClientSideTimeout2Minutes(); - assertTrue(adminSettingPage.isWarningDialogShowWhenTimeoutIsLosing()); - } - - @Test - public void testShowInformDialog(){ - AdminSettingsPage adminSettingPage = setupClientSideTimeout2Minutes(); - assertTrue(adminSettingPage.isInformDialogShowAfterTimeout()); - } - - private AdminSettingsPage setupClientSideTimeout2Minutes() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - AdminSettingsPage adminSettingPage = newDashboardPage.openAdminSettings(); - adminSettingPage.setClientSideTimeout("2"); - refreshPage(); - return adminSettingPage; - } - - @After - public void cleanupSettingAfterTest() { - redirectToRelativeLink(cleanupDataLink); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DateTimeDisplayTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DateTimeDisplayTest.java deleted file mode 100644 index 5872c47992d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DateTimeDisplayTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package portal.guitest.test; - -import java.util.regex.Pattern; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.Variable; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserProfilePage; - -public class DateTimeDisplayTest extends BaseTest { - - private static final String DATE_TIME_REGEX_PATTERN = "\\d{1,2} [a-zA-Z]+ \\d{4} \\d{2}:\\d{2}"; //Matched date: 6 July 2022 10:00 - private NewDashboardPage newDashboardPage; - - @Override - @Before - public void setup(){ - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestingTasks(); - resetLanguageOfCurrentUser(); - newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - userProfilePage.inputFormattingLanguage("English (United Kingdom)"); - newDashboardPage = userProfilePage.save(); - } - - @Test - public void testDisplayDateTime() { - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - TaskDetailsPage taskDetailsPage = taskWidget.openTaskDetails(0); - String createdDateLiteral = taskDetailsPage.getCreatedOnDateText(); - boolean matches = Pattern.matches(DATE_TIME_REGEX_PATTERN, createdDateLiteral); - - Assert.assertTrue(matches); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DefaultChartTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DefaultChartTest.java deleted file mode 100644 index b008653a76d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DefaultChartTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Set; -import java.util.stream.Collectors; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.Sleeper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.StatisticWidgetPage; - -public class DefaultChartTest extends BaseTest { - - private static final String DEFAULT_CHART = "Tasks by Priority"; - private static final String RESTORE_DEFAULT = "Restore default"; - - @Override - @Before - public void setup() { - super.setup(); - Sleeper.sleep(2000); // To make Firefox test more stable, make business data updated correctly - login(TestAccount.ADMIN_USER); - grantPermissionToCreateChart(); - } - - @After - public void clear() { - resetLanguageOfCurrentUser(); - } - - @Test - public void testCreateDefaultChart() { - new NewDashboardPage(); - MainMenuPage mainMenuPage = new MainMenuPage(); - StatisticWidgetPage statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.waitForElementDisplayed(By.id("statistics-widget:widget-container"), true); - Set chartNames = statisticWidgetPage.getAllChartNames(); - statisticWidgetPage.findListElementsByCssSelector("div[id$=':chart-name-container'] .chart-name").stream().map(e -> e.getText()).collect(Collectors.toSet()); - System.out.println("All default chart names " + chartNames); - assertTrue(chartNames.contains(DEFAULT_CHART)); - assertEquals(RESTORE_DEFAULT, statisticWidgetPage.getRestoreDefaultButtonName()); - } - - @Test - public void testRestoreDefaultChart() { - MainMenuPage mainMenuPage = new MainMenuPage(); - StatisticWidgetPage statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.waitForElementDisplayed(By.id("statistics-widget:widget-container"), true); - statisticWidgetPage.switchCreateMode(); - statisticWidgetPage.createCaseByFinishedTask(); - statisticWidgetPage.backToDashboard(); - statisticWidgetPage.restoreDefaultCharts(); - - WebElement taskByExpiryChartName3 = null ; - try { - taskByExpiryChartName3 = statisticWidgetPage.findElementById("statistics-widget:statistic-dashboard-widget:statistic-chart-repeater:2:chart-name"); - } catch (Exception ex) { - } - - assertEquals(DEFAULT_CHART, statisticWidgetPage.getChartName(0)); - assertEquals(null, taskByExpiryChartName3); - } - - private void grantPermissionToCreateChart() { - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantPortalPermission.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DisabledUserTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DisabledUserTest.java deleted file mode 100644 index 9688ec06a6e..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DisabledUserTest.java +++ /dev/null @@ -1,100 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.FileHelper; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AbsencePage; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.ExpressManagementPage; -import portal.guitest.page.ExpressProcessPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.TaskWidgetPage; - -public class DisabledUserTest extends BaseTest { - - private static final String VISIBILITY_USER_FULL_NAME = "Visibility Test User"; - private static final String DISABLED_VISIBILITY_USER_FULL_DISPLAY_NAME = - "(disabled) Visibility Test User (visibility_test_user)"; - private static final String DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME = "(disabled) Visibility Test User"; - private static final String DISABLE_VISIBILITY_USER_CREATION_LINK = "portalKitTestHelper/153CACC26D0D4C3D/disableVisibilityUser.ivp"; - private static final String TASK_CASE_CREATION_FOR_DISABLED_USER_LINK = "portalKitTestHelper/153CACC26D0D4C3D/createTaskAndCaseForDisabledUser.ivp"; - - - @Override - @Before - public void setup() { - super.setupWithAlternativeLinkAndAccount(cleanupDataLink, TestAccount.ADMIN_USER); - redirectToRelativeLink(DISABLE_VISIBILITY_USER_CREATION_LINK); - } - - @Test - public void testFilterByDisabledUserInTaskResponsibleFilter() { - redirectToRelativeLink(createTestingTasksUrl); - redirectToRelativeLink(TASK_CASE_CREATION_FOR_DISABLED_USER_LINK); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterByResponsible(VISIBILITY_USER_FULL_NAME); - assertTrue(taskWidgetPage.getFilterValue("responsible-filter").contains(DISABLED_VISIBILITY_USER_FULL_DISPLAY_NAME)); - assertEquals(1, taskWidgetPage.countTasks()); - assertEquals(DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME, taskWidgetPage.getResponsibleOfTaskAt(0)); - } - - @Test - public void testFilterByDisabledUserInCaseCreatorFilter() { - redirectToRelativeLink(createTestingTasksUrl); - redirectToRelativeLink(TASK_CASE_CREATION_FOR_DISABLED_USER_LINK); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - caseWidgetPage.openAdvancedFilter("Creator", "creator"); - caseWidgetPage.filterByCreator(VISIBILITY_USER_FULL_NAME); - assertTrue(caseWidgetPage.getFilterValue("creator-filter").contains(DISABLED_VISIBILITY_USER_FULL_DISPLAY_NAME)); - assertEquals(1, caseWidgetPage.countCases()); - assertEquals(DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME, caseWidgetPage.getCreatorAt(0)); - - } - - @Test - public void testExpressWfWithDisabledUser() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - ExpressManagementPage expressManagementPage = adminSettingsPage.openExpressManagementTab(); - expressManagementPage.openImportDialog(); - expressManagementPage.selectJSONFile(FileHelper.getAbsolutePathToTestFile("express-wf-with-disabled-user.json")); - expressManagementPage.clickOnDeployExpress(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - ProcessWidgetPage processPage = NavigationHelper.navigateToProcessList(); - ExpressProcessPage expressPage = processPage.editExpressWF("Test disabled user"); - assertEquals("Test disabled user", expressPage.getProcessName()); - assertTrue(expressPage.getProcessOwnerNames().contains(DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME)); - assertTrue(expressPage.getAbleToStartNames().contains(DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME)); - assertTrue(expressPage.getResponsiblesOfTask(1).contains(DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME)); - } - - @Test - public void testAbsenceWithDisabledUser() { - redirectToRelativeLink(cleanUpAbsencesAndSubstituesLink); - AbsencePage absencePage = new NewDashboardPage().openAbsencePage(); - absencePage.setSubstitutedByAdmin(VISIBILITY_USER_FULL_NAME); - absencePage.setDeputy(Arrays.asList(TestAccount.DEMO_USER.getFullName()), 0); - absencePage.saveSubstitute(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - absencePage = new NewDashboardPage().openAbsencePage(); - absencePage.setSubstitutedByAdmin(TestAccount.DEMO_USER.getFullName()); - assertEquals(DISABLED_VISIBILITY_USER_BRIEF_DISPLAY_NAME, absencePage.getSubstitutedByAdmin(0)); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - absencePage = new NewDashboardPage().openAbsencePage(); - absencePage.setSubstitutedByAdmin(VISIBILITY_USER_FULL_NAME); - assertEquals(TestAccount.DEMO_USER.getFullName(), absencePage.getMyDeputy(0)); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DocumentTableComponentTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DocumentTableComponentTest.java deleted file mode 100644 index b89ccf7764d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/DocumentTableComponentTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.FileHelper; -import portal.guitest.page.DocumentTableComponentPage; - -public class DocumentTableComponentTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(documentTableComponentUrl); - } - - @Test - public void testUploadDocument() { - DocumentTableComponentPage documentTableComponentPage = new DocumentTableComponentPage(); - documentTableComponentPage.uploadSampleDocument(FileHelper.getAbsolutePathToTestFile("sample-file.txt")); - refreshPage(); - documentTableComponentPage.waitForDocumentTableComponentPageLoaded(); - assertEquals(1, documentTableComponentPage.countDocuments()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/EnhanceVisibilityTasksForMemberOfRoleTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/EnhanceVisibilityTasksForMemberOfRoleTest.java deleted file mode 100644 index 0f7cc6418f7..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/EnhanceVisibilityTasksForMemberOfRoleTest.java +++ /dev/null @@ -1,117 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; - -public class EnhanceVisibilityTasksForMemberOfRoleTest extends BaseTest { - - private TaskWidgetPage taskWidgetPage; - private TaskDetailsPage taskDetailsPage; - - @Override - @Before - public void setup() { - super.setup(); - } - - @Test - public void testVisibilityTaskOpen() { - login(TestAccount.DEMO_USER); - createTestingTasks(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Suspended - TaskWidgetPage taskWidgetPageDemo = new TaskWidgetPage(); - taskWidgetPageDemo.filterByResponsible("Everybody"); - taskWidgetPageDemo.clickOnTaskStatesAndApply(Arrays.asList("Suspended")); - int countTasks = taskWidgetPageDemo.countTasks(); - // User Guest - login(TestAccount.GUEST_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Suspended - TaskWidgetPage taskWidgetPageGuest = new TaskWidgetPage(); - taskWidgetPageGuest.filterByResponsible("Everybody"); - taskWidgetPageGuest.clickOnTaskStatesAndApply(Arrays.asList("Suspended")); - assertEquals(countTasks, taskWidgetPageGuest.countTasks()); - } - - @SuppressWarnings("deprecation") - @Test - public void testVisibilityTaskInprogress() { - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - login(TestAccount.DEMO_USER); - createTestingTasks(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Suspended - TaskWidgetPage taskWidgetPageDemo = new TaskWidgetPage(); - taskWidgetPageDemo.filterByResponsible("Everybody"); - taskWidgetPageDemo.clickOnTaskStatesAndApply(Arrays.asList("Suspended")); - // Reserved - taskWidgetPageDemo.clickOnTaskActionLink(0); - taskWidgetPageDemo.reserveTask(0); - taskWidgetPageDemo.waitAjaxIndicatorDisappear(); - taskWidgetPageDemo.clickOnTaskStatesAndApply(Arrays.asList("Reserved")); - int countTasksReserved = taskWidgetPageDemo.countTasks(); - // User Guest - login(TestAccount.GUEST_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Reserved - TaskWidgetPage taskWidgetPageGuest = new TaskWidgetPage(); - taskWidgetPageGuest.filterByResponsible("Everybody"); - taskWidgetPageGuest.clickOnTaskStatesAndApply(Arrays.asList("Reserved")); - assertEquals(countTasksReserved, taskWidgetPageGuest.countTasks()); - assertFalse(taskWidgetPageGuest.isTaskStartEnabled(0)); - assertFalseTaskActionsByTaskState("Reserved", Arrays.asList("Delegate", "Reset", "Clear expiry", "Add Ad-hoc Task")); - } - - @Test - public void testVisibilityTaskDone() { - login(TestAccount.DEMO_USER); - createTestingTasks(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Suspended - TaskWidgetPage taskWidgetPageDemo = new TaskWidgetPage(); - taskWidgetPageDemo.filterByResponsible("Everybody"); - taskWidgetPageDemo.clickOnTaskStatesAndApply(Arrays.asList("Done")); - int countTasks = taskWidgetPageDemo.countTasks(); - // User Guest - login(TestAccount.GUEST_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Suspended - TaskWidgetPage taskWidgetPageGuest = new TaskWidgetPage(); - taskWidgetPageGuest.filterByResponsible("Everybody"); - taskWidgetPageGuest.clickOnTaskStatesAndApply(Arrays.asList("Done")); - assertEquals(countTasks, taskWidgetPageGuest.countTasks()); - } - - private void assertFalseTaskActionsByTaskState(String state, List taskActionInTaskDetails) { - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList(state)); - List actionInTaskList = taskWidgetPage.getActiveTaskAction(0); - actionInTaskList.remove("Details"); - actionInTaskList.remove("Workflow Events"); - assertFalse(actionInTaskList.containsAll(taskActionInTaskDetails)); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - if (taskActionInTaskDetails.isEmpty()) { - return; - } - assertTrue(taskDetailsPage.isActionLinkEnable()); - List actionInDetails = taskDetailsPage.getActiveTaskAction(); - actionInDetails.remove("Workflow Events"); - assertFalse(actionInDetails.containsAll(taskActionInTaskDetails)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressManagementTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressManagementTest.java deleted file mode 100644 index a45a5eaa2b0..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressManagementTest.java +++ /dev/null @@ -1,237 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Before; -import org.junit.Test; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.FileHelper; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.ExpressApprovalPage; -import portal.guitest.page.ExpressBusinessViewPage; -import portal.guitest.page.ExpressManagementPage; -import portal.guitest.page.ExpressReviewPage; -import portal.guitest.page.ExpressTaskPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserTaskWithMailFormPage; -import vn.wawa.guitest.base.client.Browser; - -public class ExpressManagementTest extends BaseTest { - - public static final String REQUEST_NEW_RESOURCE_PROCESS = "Request new Resources - Express process"; - private final String APPROVAL_STATUS = "Yes"; - private final String APPROVAL_USER_NAME = "Portal Admin User"; - public static final String FIRST_COMMENT = "This is great news"; - public static final String SECOND_COMMENT = "I totally agree"; - - - private NewDashboardPage newDashboardPage; - private ProcessWidgetPage processWidget; - private TaskWidgetPage taskWidgetPage; - - @Override - @Before - public void setup() { - super.setup(); - login(TestAccount.ADMIN_USER); - this.newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testImportUnsupportedExtension() { - ExpressManagementPage expressManagementPage = uploadExpressJsonFile("unsupportedExtension.abc"); - String message = expressManagementPage.getUploadMessage(); - expressManagementPage.clickOnCloseButton(); - assertEquals("Invalid file type", message); - } - - @Test - public void testImportExpressProcess() { - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - ExpressManagementPage expressManagementPage = uploadExpressJsonFile("express-test.json"); - expressManagementPage.deployExpressFile(); - adminSettingsPage.closeConfirmationDialog(); - startExpressHelperProcess("Express Test 1"); - executeUserTask(); - } - - @Test - public void testViewEmptyExpressBusinessData() { - prepareExpressWorkflowStep(); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.openCaseInfo(); - expressTaskPage.clickOnAdditionalBusinessDetailLink(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - ExpressBusinessViewPage expressBusiness = new ExpressBusinessViewPage(); - assertTrue(StringUtils.contains(expressBusiness.getTextOfCurrentBreadcrumb(), "Business Details of Case #")); - assertTrue(StringUtils.contains("There is no completed Express Task yet", expressBusiness.getEmptyFinishedTaskMessage())); - newDashboardPage = expressBusiness.clickOnCloseButton(); - } - - public void prepareExpressWorkflowStep() { - try { - if (getBrowser() == null) { - setBrowser(Browser.getBrowser()); - } - importExpressFile(FileHelper.getAbsolutePathToTestFile("express-wf-request-resource.json")); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - startExpressHelperProcess(REQUEST_NEW_RESOURCE_PROCESS); - } - - private void importExpressFile(String pathName) throws UnsupportedEncodingException { - String filepath = URLEncoder.encode(pathName, "UTF-8"); - redirectToRelativeLink("PortalKitTestHelper/153CACC26D0D4C3D/createSampleExpressWorkflowProcess.ivp?filePath=" + filepath); - } - - @Test - public void testViewExpressBusinessData() { - prepareExpressWorkflowStep(); - completeExpressWorkflowTasks(FIRST_COMMENT, SECOND_COMMENT); - openAdditionalBusinessPage(REQUEST_NEW_RESOURCE_PROCESS); - - ExpressBusinessViewPage expressBusiness = new ExpressBusinessViewPage(); - var currentStep = expressBusiness.getIndexOfCurrentProcessChain(); - assertTrue("ProcessChain should be 4 but " + currentStep, currentStep == 4); - - String fieldSetTitle = expressBusiness.getTextOfLegendFinishedTask(0); - assertEquals("Promote new resource", fieldSetTitle); - expressBusiness.clickOnLegendOfFieldset(0); - - fieldSetTitle = expressBusiness.getTextOfLegendFinishedTask(1); - assertEquals("Send email to HR", fieldSetTitle); - expressBusiness.clickOnLegendOfFieldset(1); - - fieldSetTitle = expressBusiness.getTextOfLegendFinishedTask(2); - assertEquals("HR review", fieldSetTitle); - expressBusiness.clickOnLegendOfFieldset(2); - - fieldSetTitle = expressBusiness.getTextOfLegendApprovalResult(0); - assertEquals("Approval Request", fieldSetTitle); - assertEquals(String.format("%s,%s,%s,%s,%s,%s", APPROVAL_USER_NAME, FIRST_COMMENT, APPROVAL_STATUS, APPROVAL_USER_NAME, - SECOND_COMMENT, APPROVAL_STATUS), expressBusiness.getApprovalResultsText()); - } - - public void openAdditionalBusinessPage(String caseName) { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - CaseDetailsPage caseDetailsPage = caseWidgetPage.openCaseDetailsFromActionMenuByCaseName(caseName); - caseDetailsPage.openActionMenu(); - caseDetailsPage.openAdditionalCaseDetailsPage(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - } - - public void completeExpressWorkflowTasks(String firstComment, String secondComment) { - executePromoteResourceTask(); - // Filter open Task - gotoTaskList(); - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList("Suspended")); - executeSendEmailTask(); - executeReviewTask(); - taskWidgetPage.resetFilter(); - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList("Suspended")); - executeApprovalTask(firstComment); - executeApprovalTask(secondComment); - executeFinalReviewTask(); - } - - private void gotoTaskList() { - newDashboardPage = new NewDashboardPage(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - } - - private void executeFinalReviewTask() { - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.clickOnStartTaskLink(0); - ExpressReviewPage expressReview = new ExpressReviewPage(); - expressReview.finish(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - } - - private void executeApprovalTask(String comment) { - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.clickOnStartTaskLink(0); - ExpressApprovalPage expressApproval = new ExpressApprovalPage(); - expressApproval.waitForCommentContainerDisplay(); - expressApproval.comment(comment); - expressApproval.clickOnApprove(); - } - - private void executeReviewTask() { - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.clickOnStartTaskLink(0); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.waitForExpressFieldSetDisplay(); - expressTaskPage.enterRequiredInputFieldByLabel("Comment", "Mr.David to axon"); - expressTaskPage.finish(); - } - - private void executeSendEmailTask() { - taskWidgetPage.clickOnStartTaskLink(0); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.waitForExpressFieldSetDisplay(); - expressTaskPage.enterRequiredInputFieldByLabel("Welcome", "Welcome Mr.David to axon"); - - UserTaskWithMailFormPage userTaskWithMail = new UserTaskWithMailFormPage(); - userTaskWithMail.selectEmailTab(); - userTaskWithMail.inputData("hr@email.com", "Please review this applicant", "Hello HR team, please proceed."); - userTaskWithMail.finish(); - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.filterTasksInExpandedModeBy("HR", 1); - taskWidgetPage.waitForActionGroupDisplay(); - } - - public void executePromoteResourceTask() { - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.waitForExpressFieldSetDisplay(); - expressTaskPage.enterRequiredInputFieldByLabel("Applicant name", "David Rafi"); - expressTaskPage.enterRequiredInputFieldByLabel("Email", "David@email.com"); - expressTaskPage.enterRequiredInputFieldByLabel("Address", "39b Truong Son, Tan Binh"); - expressTaskPage.finish(); - } - - private ExpressManagementPage uploadExpressJsonFile(String fileName) { - AdminSettingsPage adminSettingsPage = newDashboardPage.openAdminSettings(); - ExpressManagementPage expressManagementPage = adminSettingsPage.openExpressManagementTab(); - expressManagementPage.openImportDialog(); - expressManagementPage.selectJSONFile(FileHelper.getAbsolutePathToTestFile(fileName)); - return expressManagementPage; - } - - private void startExpressHelperProcess(String processName) { - newDashboardPage = new NewDashboardPage(); - processWidget = NavigationHelper.navigateToProcessList(); - assertTrue(processWidget.isExpandedMode()); - processWidget.enterSearchKeyword(processName); - Awaitility.await().atMost(new Duration(10, TimeUnit.SECONDS)).until(() -> processWidget.isProcessDisplay(processName)); - processWidget.startProcess(processName); - } - - private void executeUserTask() { - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.finish(); - NewDashboardPage home = new NewDashboardPage(); - home.waitForPageLoaded(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressTest.java deleted file mode 100644 index 8b0ceaac7d4..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ExpressTest.java +++ /dev/null @@ -1,144 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.ExpressApprovalPage; -import portal.guitest.page.ExpressEndPage; -import portal.guitest.page.ExpressFormDefinitionPage; -import portal.guitest.page.ExpressProcessPage; -import portal.guitest.page.ExpressReviewPage; -import portal.guitest.page.ExpressTaskPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; - -public class ExpressTest extends BaseTest{ - private static final int USER_TASK_INDEX = 0; - private static final int APPROVAL_INDEX = 3; - - private static final int INPUT_TEXT_TYPE_INDEX = 0; - private static final int INPUT_NUMBER_TYPE_INDEX = 1; - - private NewDashboardPage newDashboardPage; - private TaskWidgetPage taskWidgetPage; - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - @Override - @Before - public void setup() { - super.setup(); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testAdhocMultiApprovalWhenMultiTask() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test approval", "Test description"); - ExpressFormDefinitionPage formDefinition = configureExpressProcessWhenMultiApproval(expressProcessPage); - formDefinition.executeWorkflow(); - executeExpressProcessWhenMultiApproval(); - } - - @Test - public void testBreadCrumb() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - assertEquals("Express Workflow", expressProcessPage.getTextOfCurrentBreadcrumb()); - - expressProcessPage.fillProcessProperties(true, true, "Test approval", "Test description"); - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", Arrays.asList(responsible1)); - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - assertEquals("Express Workflow", formDefinition.getTextOfCurrentBreadcrumb()); - - newDashboardPage = formDefinition.goToHomeFromBreadcrumbWithWarning(); - assertEquals(true, newDashboardPage.isDisplayed()); - } - - private ExpressFormDefinitionPage configureExpressProcessWhenMultiApproval(ExpressProcessPage expressProcessPage) { - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible responsible2 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", Arrays.asList(responsible1, responsible2)); - - expressProcessPage.addNewTask(0); - expressProcessPage.createTask(1, APPROVAL_INDEX, "Task 2", "Task 2 description", Arrays.asList(responsible2)); - - expressProcessPage.addNewTask(1); - expressProcessPage.createTask(2, APPROVAL_INDEX, "Task 3", "Task 3 description", Arrays.asList(responsible1, responsible2)); - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text 1", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.createTextInputField("Input Number 2", INPUT_NUMBER_TYPE_INDEX, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - return formDefinition; - } - - private void executeExpressProcessWhenMultiApproval() { - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - WaitHelper.waitForNavigation(expressTaskPage, () -> expressTaskPage.finish()); - login(TestAccount.ADMIN_USER); - executeUserTask(); - login(TestAccount.DEMO_USER); - executeApproval("Approved at first level", TestAccount.DEMO_USER.getFullName()); - executeApproval("Approved at second level", TestAccount.DEMO_USER.getFullName()); - login(TestAccount.ADMIN_USER); - executeApproval("Approved at second level", "Task 3", 1, 0, TestAccount.ADMIN_USER.getFullName()); - login(TestAccount.DEMO_USER); - - String approvalResult = executeReview(); - Assert.assertEquals("Portal Demo User,Approved at first level,Yes," - + TestAccount.DEMO_USER.getFullName() + ",Approved at second level,Yes," - + TestAccount.ADMIN_USER.getFullName() + ",Approved at second level,Yes," - + TestAccount.DEMO_USER.getFullName() + ",Approved at first level,Yes," - + TestAccount.DEMO_USER.getFullName() + ",Approved at second level,Yes," - + TestAccount.ADMIN_USER.getFullName() + ",Approved at second level,Yes", approvalResult); - new ExpressEndPage().finish(); - } - - private String executeReview() { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.startTask(0); - ExpressReviewPage reviewPage = new ExpressReviewPage(); - String approvalResult = reviewPage.getApprovalResult(); - reviewPage.finish(); - return approvalResult; - } - - private void executeUserTask() { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterByResponsible(TestAccount.ADMIN_USER.getFullName()); - taskWidgetPage.startTask(0); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.finish(); - new TaskWidgetPage(); - } - - private void executeApproval(String comment, String responsible) { - executeApproval(comment, "Task", 1, 0, responsible); - } - - private void executeApproval(String comment, String taskNameFilter, int expectedNumber, int startTaskIndex, - String responsible) { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterByResponsible(responsible); - taskWidgetPage.filterTasksInExpandedModeBy(taskNameFilter, expectedNumber); - taskWidgetPage.startTask(startTaskIndex); - ExpressApprovalPage approvalPage1 = new ExpressApprovalPage(); - approvalPage1.comment(comment); - approvalPage1.approve(); - } - - private void goToExpressCreationPage() { - redirectToRelativeLink(expressStartLink); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ForgotPasswordTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ForgotPasswordTest.java deleted file mode 100644 index 0cf0c176442..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ForgotPasswordTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.SystemProperties; -import portal.guitest.common.TestAccount; -import portal.guitest.page.ForgotPasswordPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.LoginPage; -import vn.wawa.guitest.base.client.Browser; - -public class ForgotPasswordTest extends BaseTest { - private ForgotPasswordPage forgotPasswordPage; - - @Before - @Override - public void setup() { - setBrowser(Browser.getBrowser()); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - if (!SystemProperties.isInServerMode()) { - logoutDesigner(); - } - LoginPage loginPage = new LoginPage(); - loginPage.forgotPassword(); - } - - @Test - public void testForgotPassword() { - forgotPasswordPage = new ForgotPasswordPage(TestAccount.TEST_FORGOT_PASSWORD_USER); - forgotPasswordPage.send(); - assertTrue(forgotPasswordPage.isProcessed()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/FullProcessPageTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/FullProcessPageTest.java deleted file mode 100644 index 7e3856485a7..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/FullProcessPageTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.TestRole; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.ProcessWidgetPage.AddNewExternalLinkDialog; - -public class FullProcessPageTest extends BaseTest{ - - private static final String AAGOOGLE_LINK = "11AAGoogle"; - protected NewDashboardPage newDashboardPage; - protected ProcessWidgetPage processWidgetPage; - - @Override - @Before - public void setup() { - super.setup(); - newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - processWidgetPage = mainMenuPage.selectProcessesMenu(); - } - - @Test - public void testFindProcess() { - processWidgetPage.selectViewMode("COMPACT"); - processWidgetPage.waitForCompactProcessListDisplayed(); - processWidgetPage.enterSearchKeyword("Alpha Company"); - assertTrue(processWidgetPage.isProcessDisplay("Create Alpha Company")); - assertTrue(processWidgetPage.isProcessGroupDisplay("C")); - processWidgetPage.enterSearchKeyword("random keyword never match with any process"); - assertTrue(processWidgetPage.isNoProcessFound()); - assertFalse(processWidgetPage.isProcessGroupDisplay("A")); - } - - @Test - public void testChangeProcessViewMode() { - String currentView = processWidgetPage.getCurrentViewMode(); - processWidgetPage.selectViewMode(ProcessWidgetPage.GRID_MODE); - String newView = processWidgetPage.getCurrentViewMode(); - assertFalse("Current view is not changed", StringUtils.equals(currentView, newView)); - } - - @Test - public void testEditDeleteProcessIcon() { - login(TestAccount.ADMIN_USER); - newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - processWidgetPage = mainMenuPage.selectProcessesMenu(); - createPublicExternalTestProcess(AAGOOGLE_LINK, AAGOOGLE_LINK, TestRole.TESTER_ROLE); - - processWidgetPage.selectViewMode(ProcessWidgetPage.GRID_MODE); - processWidgetPage.waitForGridProcessListDisplayed(); - processWidgetPage.enterSearchKeyword("link"); - String currentIcon = processWidgetPage.getProcessItemIcon(0); - processWidgetPage.selectViewMode(ProcessWidgetPage.IMAGE_MODE); - processWidgetPage.waitForImageProcessListDisplayed(); - processWidgetPage.enterSearchKeyword("link"); - processWidgetPage.clickMoreButtonOfFirstImageProcess(); - processWidgetPage.clickOnProcessEditMenu(0); - processWidgetPage.changeProcessIcon(); - processWidgetPage.addNewRolePermission(TestRole.HR_ROLE); - processWidgetPage.saveEditProcessDialog(); - processWidgetPage.selectViewMode(ProcessWidgetPage.GRID_MODE); - processWidgetPage.waitForGridProcessListDisplayed(); - processWidgetPage.enterSearchKeyword("link"); - String newIcon = processWidgetPage.getProcessItemIcon(0); - assertFalse("Current Icon is not changed", StringUtils.equals(currentIcon, newIcon)); - - login(TestAccount.CASE_OWNER_USER); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - processWidgetPage = mainMenuPage.selectProcessesMenu(); - processWidgetPage.enterSearchKeyword(AAGOOGLE_LINK); - assertTrue(processWidgetPage.isNoProcessFound()); - - login(TestAccount.HR_ROLE_USER); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - processWidgetPage = mainMenuPage.selectProcessesMenu(); - processWidgetPage.enterSearchKeyword(AAGOOGLE_LINK); - assertTrue(processWidgetPage.isProcessDisplay(AAGOOGLE_LINK)); - - login(TestAccount.ADMIN_USER); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - processWidgetPage = mainMenuPage.selectProcessesMenu(); - processWidgetPage.selectViewMode(ProcessWidgetPage.GRID_MODE); - processWidgetPage.waitForGridProcessListDisplayed(); - processWidgetPage.enterSearchKeyword(AAGOOGLE_LINK); - processWidgetPage.clickMoreButtonOfGridProcess(AAGOOGLE_LINK); - processWidgetPage.deleteGridProcess(AAGOOGLE_LINK); - processWidgetPage.enterSearchKeyword("link"); - assertTrue("Still see processes", processWidgetPage.isNoProcessFound()); - } - - private void createPublicExternalTestProcess(String processName, String processLink, String rolePermission) { - AddNewExternalLinkDialog addNewExternalLinkDialog = processWidgetPage.openNewExternalLinkDialog(); - addNewExternalLinkDialog.inputDataForPublicExternalLink(processName, processLink, rolePermission); - addNewExternalLinkDialog.submitForm(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalGrowlTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalGrowlTest.java deleted file mode 100644 index cf81eb4a9ae..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalGrowlTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package portal.guitest.test; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; - -import org.junit.Test; - -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.BaseTest; -import portal.guitest.common.DateTimePattern; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.ExpressFormDefinitionPage; -import portal.guitest.page.ExpressProcessPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.SearchResultPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.TemplatePage; -import portal.guitest.page.TemplatePage.GlobalSearch; -import portal.guitest.page.WorkingTaskDialogPage; -import portal.guitest.page.WorkingTaskDialogPageOfApplicationMenu; - -public class GlobalGrowlTest extends BaseTest { - - private static final String FINISH_MESSAGE = "You have finished the task successfully"; - private static final String FINISH_MESSAGE_WITH_DETAILS = "You have finished the task successfully.\nClick here for details."; - private static final String CANCEL_MESSAGE = "You have cancelled and left the task successfully. You can find the task in the dashboard or your task list."; - private static final String CANCEL_MESSAGE_WITH_DETAILS = "You have cancelled and left the task successfully. You can find the task in the dashboard or your task list.\nClick here for details."; - - // TODO Write test for Growl in IFrame, in version 10 it has the test public void - // testDisplayCustomGrowlAfterFinishTask() - - @Test - public void testDisplayDefaultGrowlAfterFinishTask() { - redirectToRelativeLink(createTestingTasksUrl); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - taskTemplatePage.inputFields("Employee", today, today, "Representation"); - taskWidgetPage = taskTemplatePage.clickSubmitButton(); - assertGrowlMessage(taskWidgetPage, FINISH_MESSAGE_WITH_DETAILS); - } - - // TODO Write test for Growl in IFrame, in version 10 it has the test public void - // testDisplayDefaultGrowlAfterFinishFirstTask() - - @Test - public void testDisplayDefaultGrowlAfterCancelTask() { - redirectToRelativeLink(createTestingTasksUrl); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - taskWidgetPage = taskTemplatePage.clickCancelAndLeftButton(); - assertGrowlMessage(taskWidgetPage, CANCEL_MESSAGE_WITH_DETAILS); - } - - // TODO Write test for Growl in IFrame, in version 10 it has the test public void - // testDisplayCustomGrowlAfterCancelTask() - - // TODO Write test for Growl in IFrame, in version 10 it has the test public void - // testDisplayDefaultGrowlAfterCancelFirstTask() - - @Test - public void testSaveExpressFormDefinition() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(false, true, "Test approval", "Test description"); - ExpressFormDefinitionPage formDefinition = configureExpressProcess(expressProcessPage); - NewDashboardPage newDashboardPage = formDefinition.save(); - assertGrowlMessage(newDashboardPage, FINISH_MESSAGE_WITH_DETAILS); - } - - @Test - public void testFinishExpressFormDefinition() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(false, true, "Test approval", "Test description"); - ExpressFormDefinitionPage formDefinition = configureExpressProcess(expressProcessPage); - formDefinition.finishWorkflow(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertGrowlMessage(newDashboardPage, FINISH_MESSAGE); - } - - private ExpressFormDefinitionPage configureExpressProcess(ExpressProcessPage expressProcessPage) { - ExpressResponsible responsible = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - expressProcessPage.createTask(0, 0, "Task 1", "Task 1 description", Arrays.asList(responsible)); - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text", 0, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - return formDefinition; - } - - @Test - public void testTaskLeft() { - leftTaskWhenClickingOnLogo(); - leftTaskWhenClickingOnMenu(); - leftTaskWhenGlobalSearch(); - leftExpressWorkflowDefinition(); - leftExpressFormDefinition(); - } - - private void leftExpressFormDefinition() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test approval", "Test description"); - expressProcessPage.createTask(0, 0, "Task 1", "Task 1 description", - Arrays.asList(new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false))); - ExpressFormDefinitionPage expressFormDefinitionPage = expressProcessPage.goToFormDefinition(); - NewDashboardPage newDashboardPage = expressFormDefinitionPage.cancel(); - assertGrowlMessage(newDashboardPage, CANCEL_MESSAGE); - } - - private void leftExpressWorkflowDefinition() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - NewDashboardPage newDashboardPage = expressProcessPage.cancelWorkflowDefinition(); - assertGrowlMessage(newDashboardPage, CANCEL_MESSAGE); - } - - private void leftTaskWhenGlobalSearch() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - GlobalSearch globalSearch = expressProcessPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword("a"); - assertGrowlMessage(searchResultPage, CANCEL_MESSAGE); - } - - private void leftTaskWhenClickingOnMenu() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - MainMenuPage mainMenuPage = expressProcessPage.openMainMenu(); - WorkingTaskDialogPageOfApplicationMenu leaveTaskDialogOfMenu = mainMenuPage.selectDashboardMenu(); - NewDashboardPage newDashboardPage = leaveTaskDialogOfMenu.leaveTask(); - assertGrowlMessage(newDashboardPage, CANCEL_MESSAGE); - } - - private void leftTaskWhenClickingOnLogo() { - redirectToRelativeLink(expressStartLink); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.clickOnLogo(); - WorkingTaskDialogPage dialogPage = new WorkingTaskDialogPage(); - NewDashboardPage newDashboardPage = dialogPage.leaveTask(); - assertGrowlMessage(newDashboardPage, CANCEL_MESSAGE); - } - - private void assertGrowlMessage(TemplatePage templatePage, String message) { - WaitHelper.assertTrueWithWait(() -> templatePage.getGlobalGrowlMessage().equals(message)); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalSearchTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalSearchTest.java deleted file mode 100644 index c59c81b5828..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/GlobalSearchTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package portal.guitest.test; - -import static portal.guitest.common.Variable.SHOW_GLOBAL_SEARCH; - -import org.junit.Assert; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TemplatePage.GlobalSearch; - -public class GlobalSearchTest extends BaseTest{ - - private NewDashboardPage newDashboardPage; - private GlobalSearch globalSearch; - @Test - public void testHideGlobalSearch() { - updatePortalSetting(SHOW_GLOBAL_SEARCH.getKey(), "false"); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - globalSearch = newDashboardPage.getGlobalSearch(); - Assert.assertFalse(globalSearch.isPresent()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LanguageSettingTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LanguageSettingTest.java deleted file mode 100644 index d40daa97612..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LanguageSettingTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserProfilePage; -import portal.guitest.page.WorkingTaskDialogFromUserProfilePage; - -public class LanguageSettingTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - createTestData(); - } - - @Test - public void testChangeLanguageWhenWorkingOnTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.startTask(0); - taskWidgetPage.clickOnMyProfile(); - WorkingTaskDialogFromUserProfilePage workingTaskDialogPage = new WorkingTaskDialogFromUserProfilePage(); - workingTaskDialogPage.leaveTask(); - UserProfilePage userProfilePage = new UserProfilePage(); - assertEquals("Language", userProfilePage.getLanguageSettingTitle()); - } - - @Test - public void testChangeLanguage() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - // select German - userProfilePage.selectLanguage(3); - newDashboardPage = userProfilePage.save(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - assertEquals("Prozesse", mainMenuPage.getProcessMenuItemText()); - userProfilePage = newDashboardPage.openMyProfilePage(); - userProfilePage.selectLanguage(1); - userProfilePage.save(); - mainMenuPage = userProfilePage.openMainMenu(); - assertEquals("Processes", mainMenuPage.getProcessMenuItemText()); - } - - private void createTestData() { - redirectToRelativeLink(createTestingTasksUrl); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LoginTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LoginTest.java deleted file mode 100644 index f651c49fb9c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/LoginTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.SystemProperties; -import portal.guitest.common.TestAccount; -import portal.guitest.page.ForgotPasswordPage; -import portal.guitest.page.LoginPage; -import portal.guitest.page.NewDashboardPage; -import vn.wawa.guitest.base.client.Browser; - -public class LoginTest extends BaseTest { - private LoginPage loginPage; - - @Before - @Override - public void setup() { - setBrowser(Browser.getBrowser()); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - if (!SystemProperties.isInServerMode()) { - logoutDesigner(); - } - } - - @Test - public void testLogin() { - loginPage = new LoginPage(TestAccount.DEMO_USER); - loginPage.login(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertTrue(newDashboardPage.isDisplayed()); - } - - @Test - public void testForgotPassword() { - loginPage = new LoginPage(); - loginPage.forgotPassword(); - ForgotPasswordPage forgotPasswordPage = new ForgotPasswordPage(); - assertTrue(forgotPasswordPage.isDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/MenuTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/MenuTest.java deleted file mode 100644 index f3d3c01c2e3..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/MenuTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; - -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.WebDriver; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.StatisticWidgetPage; -import portal.guitest.page.TaskWidgetPage; -import vn.wawa.guitest.base.client.Browser; - -public class MenuTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - } - - @Test - public void testKeepOpenStateWhenNavigateToAnotherPage() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - TaskWidgetPage taskWidgetPage = mainMenuPage.selectTaskMenu(); - assertTrue(taskWidgetPage.isMainMenuOpen()); - } - - @Test - public void testKeepClosedStateWhenNavigateToAnotherPage() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - StatisticWidgetPage dashboardPage = mainMenuPage.selectStatisticDashboard(); - dashboardPage.waitForPageLoaded(); - - dashboardPage.closeMainMenu(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - assertFalse(newDashboardPage.isMainMenuOpen()); - } - - @Test - public void testNavigateToThirdPartyApp() { - createThirdPartyApp(); - login(TestAccount.DEMO_USER); - // to refresh cache - login(TestAccount.ADMIN_USER); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - mainMenuPage.clickThirdPartyApp(); - - WebDriver driver = Browser.getBrowser().getDriver(); - WaitHelper.assertTrueWithWait(() -> driver.getWindowHandles().size() > 1); - ArrayList tabs = new ArrayList (driver.getWindowHandles()); - driver.switchTo().window(tabs.get(1)); - WaitHelper.assertTrueWithWait(() -> "Google".equals(driver.getTitle())); - assertEquals("https://www.google.com/", driver.getCurrentUrl()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PageRefreshingTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PageRefreshingTest.java deleted file mode 100644 index deb135463f1..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PageRefreshingTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; - -public class PageRefreshingTest extends BaseTest { - - @Override - @Before - public void setup() { - killBrowsers(); - super.setup(); - createTestingTasks(); - } - - @Test - public void testTasksInPortalTaskPageUpdatedAfterReloading() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - - TaskWidgetPage taskWidgetPage = mainMenuPage.selectTaskMenu(); - assertEquals(3, taskWidgetPage.countTasks()); - - launchBrowserAndGotoRelativeLink(createTestingTasksUrl); - taskWidgetPage.refresh(); - assertEquals(6, taskWidgetPage.countTasks()); - } - - @AfterClass - public static void killOpenBrowsers() { - killBrowsers(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordChangeTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordChangeTest.java deleted file mode 100644 index 62ddcd8067f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordChangeTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.SystemProperties; -import portal.guitest.common.TestAccount; -import portal.guitest.page.ChangePasswordPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.LoginPage; - -public class PasswordChangeTest extends BaseTest { - - - @Override - @Before - public void setup() { - setupWithAlternativeLinkAndAccount("portalKitTestHelper/153CACC26D0D4C3D/createTestUser.ivp", TestAccount.TEST_CHANGE_PASSWORD_USER); - } - - @Test - public void passwordChangeTest() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - - String newPassword = "abc"; - - ChangePasswordPage changePasswordPage = newDashboardPage.openChangePasswordPage(); - - changePasswordPage.changePassword("random password", newPassword); - assertTrue(changePasswordPage.isWrongCurrentPasswordError()); - - changePasswordPage.changePassword(TestAccount.TEST_CHANGE_PASSWORD_USER.getPassword(), newPassword); - assertTrue(changePasswordPage.isNewPasswordNotStrongEnough()); - - newPassword = "a2C!"; - changePasswordPage.changePassword(TestAccount.TEST_CHANGE_PASSWORD_USER.getPassword(), newPassword); - if (!SystemProperties.isInServerMode()) { - launchBrowserAndLogoutInDesigner(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - } else { - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - } - new LoginPage(TestAccount.TEST_CHANGE_PASSWORD_USER).login(TestAccount.TEST_CHANGE_PASSWORD_USER.getUsername(), - newPassword); - - assertTrue(newDashboardPage.isDisplayed()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordResetTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordResetTest.java deleted file mode 100644 index 2a8926d2e7f..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordResetTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.SystemProperties; -import portal.guitest.common.TestAccount; -import portal.guitest.page.ForgotPasswordPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.LoginPage; -import portal.guitest.page.PasswordResetErrorPage; -import portal.guitest.page.PasswordResetPage; -import vn.wawa.guitest.base.client.Browser; - -public class PasswordResetTest extends BaseTest { - private PasswordResetPage passwordResetPage; - private PasswordResetErrorPage passwordResetErrorPage; - - @Before - @Override - public void setup() { - setBrowser(Browser.getBrowser()); - launchBrowserAndGotoRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - if (!SystemProperties.isInServerMode()) { - logoutDesigner(); - } - redirectToRelativeLink(portalKitTestHelperPasswordResetUrl); - } - - @Test - public void testResetPasswordSuccess() { - redirectToRelativeLink(String.format(portalPasswordResetUrl, TestAccount.TEST_FORGOT_PASSWORD_USER.getPassword(), TestAccount.TEST_FORGOT_PASSWORD_USER.getUsername())); - passwordResetPage = new PasswordResetPage(); - String newPassword = "a2C!"; - passwordResetPage.resetPassword(newPassword, true); - assertTrue(passwordResetPage.isReset()); - passwordResetPage.goHome(); - LoginPage loginPage = new LoginPage(); - assertTrue(loginPage.isDisplayed()); - } - - @Test - public void testResetPasswordFailedWithWeakPassword() { - redirectToRelativeLink(String.format(portalPasswordResetUrl, TestAccount.TEST_FORGOT_PASSWORD_USER.getPassword(), TestAccount.TEST_FORGOT_PASSWORD_USER.getUsername())); - passwordResetPage = new PasswordResetPage(); - - String newPassword = "abc"; - passwordResetPage.resetPassword(newPassword, false); - assertTrue(passwordResetPage.isNewPasswordNotStrongEnough()); - } - - @Test - public void testResetPasswordFailed() { - redirectToRelativeLink(String.format(portalPasswordResetUrl, "1234", TestAccount.TEST_FORGOT_PASSWORD_USER.getUsername())); - passwordResetErrorPage = new PasswordResetErrorPage(); - assertTrue(passwordResetErrorPage.isDisplayed()); - passwordResetErrorPage.goForgotPassword(); - ForgotPasswordPage forgotPasswordPage = new ForgotPasswordPage(); - assertTrue(forgotPasswordPage.isDisplayed()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordValidationTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordValidationTest.java deleted file mode 100644 index ad716ba73c2..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PasswordValidationTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.TimeUnit; - -import org.junit.Before; -import org.junit.Test; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import ch.ivy.addon.portalkit.enums.PortalPermission; -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.PasswordValidationPage; - -public class PasswordValidationTest extends BaseTest { - - private NewDashboardPage newDashboardPage; - private AdminSettingsPage adminSettingsPage; - private PasswordValidationPage passwordValidationPage; - - @Before - @Override - public void setup() { - super.setup(); - login(TestAccount.ADMIN_USER); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testVisibilityForPasswordValidationTab() { - accessToPasswordValidation(); - assertTrue("PasswordValidation tab is not displayed", passwordValidationPage.isDisplayed()); - - denySpecificPortalPermission(PortalPermission.PASSWORD_VALIDATION); - newDashboardPage = new NewDashboardPage(); - adminSettingsPage = newDashboardPage.openAdminSettings(); - assertFalse("PasswordValidation tab is displayed", adminSettingsPage.isPasswordValidationTabViewPresent()); - } - - @Test - public void testVisibilityForEnablePasswordValidationToggle() { - grantSpecificPortalPermission(PortalPermission.PASSWORD_VALIDATION); - accessToPasswordValidation(); - assertTrue("Enable Password Validation toggle is not displayed", - passwordValidationPage.isPasswordValidationTogglePresent()); - } - - @Test - public void testSaveButtonDisableAsDefault() { - grantSpecificPortalPermission(PortalPermission.PASSWORD_VALIDATION); - accessToPasswordValidation(); - assertFalse("Save button is not disabled as default", passwordValidationPage.isEnableSaveButton()); - } - - @Test - public void testSaveButtonEnableAfterSwitchPasswordValidationToggle() { - grantSpecificPortalPermission(PortalPermission.PASSWORD_VALIDATION); - accessToPasswordValidation(); - passwordValidationPage.clickOnPasswordValidationToggle(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> passwordValidationPage.isEnableSaveButton()); - assertTrue("Save button is not enabled after click on enable password validation toggle", - passwordValidationPage.isEnableSaveButton()); - } - - @Test - public void testEnablePolicyTableAfterEnablePasswordValidationToggle() { - grantSpecificPortalPermission(PortalPermission.PASSWORD_VALIDATION); - accessToPasswordValidation(); - if (!passwordValidationPage.isPasswordValidationToggleChecked()) { - passwordValidationPage.clickOnPasswordValidationToggle(); - } - assertTrue("Password policy table is not enabled", passwordValidationPage.isCheckBoxInTableEnabled()); - } - - @Test - public void testSaveButtonDisabledAfterClickSaveButton() { - grantSpecificPortalPermission(PortalPermission.PASSWORD_VALIDATION); - accessToPasswordValidation(); - passwordValidationPage.clickOnPasswordValidationToggle(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> passwordValidationPage.isEnableSaveButton()); - passwordValidationPage.clickOnSaveButton(); - assertFalse("Save button is not enabled after click on enable password validation toggle", - passwordValidationPage.isEnableSaveButton()); - } - - private PasswordValidationPage accessToPasswordValidation() { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - var adminSettingsPage = new NewDashboardPage().openAdminSettings(); - assertTrue("PasswordValidation tab is NOT displayed", adminSettingsPage.isPasswordValidationTabViewPresent()); - passwordValidationPage = adminSettingsPage.openPasswordValidationTab(); - return passwordValidationPage; - } -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalExpressTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalExpressTest.java deleted file mode 100644 index be466feee7c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalExpressTest.java +++ /dev/null @@ -1,512 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.Dimension; -import org.openqa.selenium.WebElement; - -import ch.ivy.addon.portalkit.util.ScreenshotUtil; -import portal.guitest.bean.ExpressResponsible; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.DefaultExpresTaskPage; -import portal.guitest.page.ExpressApprovalPage; -import portal.guitest.page.ExpressEndPage; -import portal.guitest.page.ExpressFormDefinitionPage; -import portal.guitest.page.ExpressProcessPage; -import portal.guitest.page.ExpressReviewPage; -import portal.guitest.page.ExpressTaskPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.SearchResultPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.TemplatePage.GlobalSearch; -import portal.guitest.page.UserTaskWithMailFormPage; - -public class PortalExpressTest extends BaseTest { - protected static final int USER_TASK_INDEX = 0; - protected static final int USER_TASK_WITH_EMAIL_INDEX = 1; - protected static final int INFORMATION_EMAIL_INDEX = 2; - protected static final int APPROVAL_INDEX = 3; - - protected static final int INPUT_TEXT_TYPE_INDEX = 0; - protected static final int INPUT_NUMBER_TYPE_INDEX = 1; - protected static final int INPUT_DATE_TYPE_INDEX = 2; - - protected NewDashboardPage newDashboardPage; - protected ProcessWidgetPage processWidget; - protected TaskWidgetPage taskWidgetPage; - - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible responsible2 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - ExpressResponsible groupHr = new ExpressResponsible("Human resources department", true); - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink("portalKitTestHelper/14DE09882B540AD5/grantPortalPermission.ivp"); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testOpenProcessWidgetWithoutCreateExpressWorkflowPermission() throws Exception { - String denyAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/denyPortalPermission.ivp"; - redirectToRelativeLink(denyAllPermissionsForAdminUserURL); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - processWidget = mainMenuPage.selectProcessesMenu(); - assertEquals(false, processWidget.hasCreateNewExpressWorkflowLink()); - // run process to grant permission back to normal - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantPortalPermission.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - @Test - public void testCreateDocumentElement() { - goToCreateExpressProcess(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test 1", "Test description"); - - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", Arrays.asList(responsible1)); - - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createUploadComponent("Upload"); - formDefinition.moveAllElementToDragAndDrogPanel(); - formDefinition.executeWorkflow(); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - Assert.assertTrue(expressTaskPage.isDocumentTableVisible()); - Assert.assertTrue(expressTaskPage.isDocumentUploadButtonVisible()); - expressTaskPage.finish(); - } - - @Test - public void createFullElementsOfForm() { - ScreenshotUtil.resizeBrowser(new Dimension(2560, 1440)); - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test 1", "Test description"); - - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", Arrays.asList(responsible1)); - - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.createTextInputField("Input number", INPUT_NUMBER_TYPE_INDEX, true); - formDefinition.createTextInputField("Input date", INPUT_DATE_TYPE_INDEX, true); - formDefinition.createRadioButtonField("Radio", 3); - formDefinition.createUploadComponent("Upload"); - formDefinition.createCheckboxField("Checkbox", 3); - formDefinition.createTextAreaField("Text area", true); - formDefinition.createCheckboxFieldWithDataProvider("Checkbox with data provider"); - formDefinition.moveAllElementToDragAndDrogPanel(); - - Assert.assertEquals(14, formDefinition.countNumberOfElementsInPreviewDialog()); - Assert.assertNotNull(formDefinition.findElementByXpath("//label[text()='Data Provider Item 1']")); - Assert.assertNotNull(formDefinition.findElementByXpath("//label[text()='Data Provider Item 2']")); - Assert.assertNotNull(formDefinition.findElementByXpath("//label[text()='Data Provider Item 3']")); - } - - @Test - public void createFullTaskType() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test full task type", "Test description"); - - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible responsible2 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", - Arrays.asList(responsible1, responsible2)); - - expressProcessPage.addNewTask(0); - expressProcessPage.createTask(1, USER_TASK_WITH_EMAIL_INDEX, "Task 2", "Task 2 description", - Arrays.asList(responsible2)); - - expressProcessPage.addNewTask(1); - expressProcessPage.createTask(2, INFORMATION_EMAIL_INDEX, null, null, null); - - expressProcessPage.addNewTask(2); - expressProcessPage.createTask(3, APPROVAL_INDEX, "Task 4", "Task 4 description", Arrays.asList(responsible1)); - - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - Assert.assertEquals(4, formDefinition.countNumberOfSteps()); - } - - @Test - public void testStartFirstTaskIfCreatorIsAssigned() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test 1 Process for creator", - "Test description Process for creator"); - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task for creator", "Task 1 description for creator", - Arrays.asList(responsible2)); - - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - formDefinition.executeWorkflow(); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.finish(); - NewDashboardPage home = new NewDashboardPage(); - assertTrue(home.isDisplayed()); - } - - @Test - public void createUserDefaultProcess() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.waitForPageLoaded(); - expressProcessPage.fillProcessProperties(true, false, "Test create default process", "Test description"); - - ExpressResponsible demoResponsible = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - expressProcessPage.createDefaultTask(0, "Default Task", Arrays.asList(demoResponsible)); - expressProcessPage.addNewTask(0); - expressProcessPage.createDefaultTask(1, "Next Default Task", Arrays.asList(demoResponsible)); - expressProcessPage.executeDirectly(); - - DefaultExpresTaskPage defaultExpresTaskPage = new DefaultExpresTaskPage(); - defaultExpresTaskPage.enterTextToDefaultTask("Test input"); - defaultExpresTaskPage.finishDefaultTask(); - - taskWidgetPage = new NewDashboardPage().openTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Next Default Task"); - taskWidgetPage.startTask(0); - defaultExpresTaskPage = new DefaultExpresTaskPage(); - defaultExpresTaskPage.enterTextToDefaultTask("Comment"); - defaultExpresTaskPage.finishDefaultTask(); - - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.filterTasksInExpandedModeBy("Test create default process: Final Review"); - taskWidgetPage.startTask(0); - - ExpressReviewPage reviewPage = new ExpressReviewPage(); - reviewPage.finish(); - } - - @Test - public void testMultiApprovalWhenMultiTask() { - createAdministratedWorkflow("Test approval", Arrays.asList(responsible1, groupHr), true); - startExpressProcess("Test approval"); - executeExpressProcessWhenMultiApproval(); - } - - @Test - public void testAbleToStartAdministratedWorkflow() { - createAdministratedWorkflow("Test approval", Arrays.asList(responsible1, groupHr), false); - // responsible1, groupHr is able to start process - login(TestAccount.ADMIN_USER); - startExpressProcess("Test approval"); - login(TestAccount.HR_ROLE_USER); - startExpressProcess("Test approval"); - // creator is able to start process - login(TestAccount.DEMO_USER); - startExpressProcess("Test approval"); - } - - @Test - public void testUserAdminCanViewEditDeleteProcess() { - createAdministratedWorkflow("Test approval", Arrays.asList(responsible1, groupHr), false); - login(TestAccount.ADMIN_USER); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword("Test approval"); - searchResultPage.waitForFirstTabFinishedLoading(); - - WebElement expressWorkflow = searchResultPage.findElementByClassName("express-workflow"); - WebElement moreMenuButton = - searchResultPage.findChildElementByCssSelector(expressWorkflow, "button[id$=':process-action-button']"); - moreMenuButton.click(); - - assertTrue(searchResultPage.isInfoWorkflowIcon()); - assertTrue(searchResultPage.isEditExpressWorkflow("Test approval")); - assertTrue(searchResultPage.isDeleteExpressWorkflown("Test approval")); - assertTrue(searchResultPage.isExpressProcessLogo()); - } - - @Test - public void testUserCreatorCanViewEditDeleteProcess() { - createAdministratedWorkflow("Test approval", Arrays.asList(responsible1, groupHr), false); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword("Test approval"); - searchResultPage.waitForFirstTabFinishedLoading(); - WebElement expressWorkflow = searchResultPage.findElementByClassName("express-workflow"); - WebElement moreMenuButton = - searchResultPage.findChildElementByCssSelector(expressWorkflow, "button[id$=':process-action-button']"); - moreMenuButton.click(); - - assertTrue(searchResultPage.isInfoWorkflowIcon()); - assertTrue(searchResultPage.isEditExpressWorkflow("Test approval")); - assertTrue(searchResultPage.isDeleteExpressWorkflown("Test approval")); - assertTrue(searchResultPage.isExpressProcessLogo()); - } - - @Test - public void testProcessOwnerCanViewAndEditProcess() { - createAdministratedWorkflow("Test approval", Arrays.asList(responsible1, groupHr), false); - login(TestAccount.HR_ROLE_USER); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword("Test approval"); - searchResultPage.waitForFirstTabFinishedLoading(); - - assertTrue(searchResultPage.isInfoWorkflowIcon()); - assertTrue(searchResultPage.isExpressProcessLogo()); - - WebElement expressWorkflow = searchResultPage.findElementByClassName("express-workflow"); - WebElement moreMenuButton = - searchResultPage.findChildElementByCssSelector(expressWorkflow, "button[id$=':process-action-button']"); - moreMenuButton.click(); - - assertTrue(searchResultPage.isEditExpressWorkflow("Test approval")); - assertTrue(searchResultPage.isDeleteExpressWorkflown("Test approval")); - } - - @Test - public void testAbleToStartCanViewProcess() { - login(TestAccount.ADMIN_USER); - createAdministratedWorkflow("Test approval", Arrays.asList(groupHr), false); - login(TestAccount.DEMO_USER); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword("Test approval"); - searchResultPage.waitForFirstTabFinishedLoading(); - - assertTrue(searchResultPage.isInfoWorkflowIcon()); - assertTrue(searchResultPage.isExpressProcessLogo()); - } - - @Test - public void testRejectedApprovalWhenMultiTask() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(false, true, "Test approval", "Test description"); - expressProcessPage.fillProcessOwners(Arrays.asList(responsible1, groupHr)); - ExpressFormDefinitionPage formDefinition = configureExpressProcessWhenMultiApproval(expressProcessPage); - formDefinition.finishWorkflow(); - startExpressProcess("Test approval"); - rejectWhenMultiApproval(); - } - - @Test - public void testComplexProcess() { - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(true, true, "Test approval", "Test description"); - ExpressFormDefinitionPage formDefinition = configureComplexProcess(expressProcessPage); - formDefinition.executeWorkflowAndWaitForUserTaskWithEmailDisplay(); - executeComplexProcess(); - } - - private void createAdministratedWorkflow(String expressProcessName, List processOwners, - Boolean isMultiApproved) { - ExpressFormDefinitionPage formDefinition; - goToExpressCreationPage(); - ExpressProcessPage expressProcessPage = new ExpressProcessPage(); - expressProcessPage.fillProcessProperties(false, true, expressProcessName, "Test description"); - expressProcessPage.fillProcessOwners(processOwners); - if (isMultiApproved) { - formDefinition = configureExpressProcessWhenMultiApproval(expressProcessPage); - } else { - formDefinition = configureExpressProcessWhenOneApproval(expressProcessPage); - } - formDefinition.finishWorkflow(); - } - - protected void rejectWhenMultiApproval() { - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.finish(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - var taskWidgetPage = newDashboardPage.openTaskList(); - if (taskWidgetPage.countTasks() != 1) { - WaitHelper.waitForNavigation(taskWidgetPage, () -> taskWidgetPage.openTaskList()); - if (taskWidgetPage.countTasks() != 1) { - WaitHelper.waitForNavigation(taskWidgetPage, () -> taskWidgetPage.openTaskList()); - } - } - assertEquals(1, new TaskWidgetPage().countTasks()); - rejectApproval("Rejected at first level"); - String approvalResult = executeReview(); - Assert.assertEquals("Portal Demo User,Rejected at first level,No", - approvalResult); - new ExpressEndPage().finish(); - } - - protected ExpressFormDefinitionPage configureExpressProcessWhenOneApproval(ExpressProcessPage expressProcessPage) { - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible responsible2 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", - Arrays.asList(responsible1, responsible2)); - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text 1", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.createTextInputField("Input Number 2", INPUT_NUMBER_TYPE_INDEX, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - return formDefinition; - } - - protected ExpressFormDefinitionPage configureExpressProcessWhenMultiApproval( - ExpressProcessPage expressProcessPage) { - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible responsible2 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_INDEX, "Task 1", "Task 1 description", - Arrays.asList(responsible1, responsible2)); - - expressProcessPage.addNewTask(0); - expressProcessPage.createTask(1, APPROVAL_INDEX, "Task 2", "Task 2 description", Arrays.asList(responsible2)); - - expressProcessPage.addNewTask(1); - expressProcessPage.createTask(2, APPROVAL_INDEX, "Task 3", "Task 3 description", - Arrays.asList(responsible1, responsible2)); - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text 1", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.createTextInputField("Input Number 2", INPUT_NUMBER_TYPE_INDEX, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - return formDefinition; - } - - protected ExpressFormDefinitionPage configureComplexProcess(ExpressProcessPage expressProcessPage) { - ExpressResponsible responsible1 = new ExpressResponsible(TestAccount.ADMIN_USER.getUsername(), false); - ExpressResponsible responsible2 = new ExpressResponsible(TestAccount.DEMO_USER.getUsername(), false); - - expressProcessPage.createTask(0, USER_TASK_WITH_EMAIL_INDEX, "Task 1", "Task 1 description", - Arrays.asList(responsible2)); - - expressProcessPage.addNewTask(0); - expressProcessPage.createTask(1, APPROVAL_INDEX, "Task 2", "Task 2 description", Arrays.asList(responsible2)); - - expressProcessPage.addNewTask(1); - expressProcessPage.createTask(2, INFORMATION_EMAIL_INDEX, "Task 3", "Task 3 description", - Arrays.asList(responsible1, responsible2)); - expressProcessPage.addNewTask(2); - expressProcessPage.createTask(3, USER_TASK_INDEX, "Task 4", "Task 4 description", Arrays.asList(responsible2)); - ExpressFormDefinitionPage formDefinition = expressProcessPage.goToFormDefinition(); - formDefinition.createTextInputField("Input Text", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - formDefinition.nextStep(); - formDefinition.inputMailRecipient("wawa@axongroupio.ch"); - formDefinition.inputMailSubject("Information for task 2"); - formDefinition.inputMailContent("Task is finished"); - formDefinition.nextStep(); - formDefinition = new ExpressFormDefinitionPage(); - formDefinition.createTextInputField("Input Text 1", INPUT_TEXT_TYPE_INDEX, false); - formDefinition.createTextInputField("Input Number 2", INPUT_NUMBER_TYPE_INDEX, false); - formDefinition.moveAllElementToDragAndDrogPanel(); - return formDefinition; - } - - protected void executeExpressProcessWhenMultiApproval() { - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.finish(); - executeApproval("Approved at first level", 0); - executeApproval("Approved at second level", 0); - login(TestAccount.ADMIN_USER); - executeApproval("Approved at second level", 1, "Task 3", 2); - login(TestAccount.DEMO_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - String approvalResult = executeReview(); - Assert.assertEquals("Portal Demo User,Approved at first level,Yes," + TestAccount.DEMO_USER.getFullName() - + ",Approved at second level,Yes," + TestAccount.ADMIN_USER.getFullName() - + ",Approved at second level,Yes", approvalResult); - new ExpressEndPage().finish(); - } - - protected void executeComplexProcess() { - UserTaskWithMailFormPage userTaskWithMailFormPage = new UserTaskWithMailFormPage(); - userTaskWithMailFormPage.waitForPageLoaded(); - userTaskWithMailFormPage.selectEmailTab(); - userTaskWithMailFormPage.inputData("wawa@axongroupio.ch", "Task information", "Task is created"); - userTaskWithMailFormPage.finish(); - new NewDashboardPage(); - executeApproval("Approved at first level", 0); - executeUserTask(); - String approvalResult = executeReview("Test approval: Final Review"); - Assert.assertEquals("Portal Demo User,Approved at first level,Yes", approvalResult); - new ExpressEndPage().finish(); - } - - protected String executeReview() { - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.startTask(0); - ExpressReviewPage reviewPage = new ExpressReviewPage(); - String approvalResult = reviewPage.getApprovalResult(); - reviewPage.finish(); - return approvalResult; - } - - protected String executeReview(String taskName) { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy(taskName); - taskWidgetPage.startTask(0); - ExpressReviewPage reviewPage = new ExpressReviewPage(); - String approvalResult = reviewPage.getApprovalResult(); - reviewPage.finish(); - return approvalResult; - } - - protected void executeUserTask() { - taskWidgetPage = new TaskWidgetPage(); - WaitHelper.assertTrueWithRefreshPage(taskWidgetPage, () -> taskWidgetPage.countTasks() == 1); - taskWidgetPage.startTask(0); - ExpressTaskPage expressTaskPage = new ExpressTaskPage(); - expressTaskPage.finish(); - taskWidgetPage = new TaskWidgetPage(); - } - - protected void startExpressProcess(String processName) { - newDashboardPage = new NewDashboardPage(); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(processName); - searchResultPage.waitForFirstTabFinishedLoading(); - searchResultPage.startProcess(processName); - new TaskTemplatePage().isDisplayed(); - } - - protected void executeApproval(String comment, int taskIndex, String taskNameFilter, int taskCountAfterFiltering) { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - if (taskWidgetPage.countTasks() <= taskIndex) { - taskWidgetPage.filterTasksInExpandedModeBy("Task", taskCountAfterFiltering); - } - if (StringUtils.isNotEmpty(taskNameFilter)) { - taskWidgetPage.filterTasksInExpandedModeBy(taskNameFilter, taskCountAfterFiltering); - } - taskWidgetPage.startTask(taskIndex); - ExpressApprovalPage approvalPage1 = new ExpressApprovalPage(); - approvalPage1.comment(comment); - approvalPage1.approve(); - } - - protected void executeApproval(String comment, int taskIndex) { - executeApproval(comment, taskIndex, null, 1); - } - - protected void rejectApproval(String comment) { - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.startTask(0); - ExpressApprovalPage approvalPage1 = new ExpressApprovalPage(); - approvalPage1.comment(comment); - approvalPage1.reject(); - } - - protected void goToExpressCreationPage() { - redirectToRelativeLink(expressStartLink); - } - - protected void goToCreateExpressProcess() { - processWidget = NavigationHelper.navigateToProcessList(); - processWidget.openExpressPage(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalPermissionTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalPermissionTest.java deleted file mode 100644 index bc86f78add9..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/PortalPermissionTest.java +++ /dev/null @@ -1,175 +0,0 @@ -package portal.guitest.test; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import ch.ivy.addon.portalkit.enums.PortalPermission; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.Variable; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; - -public class PortalPermissionTest extends BaseTest{ - - protected NewDashboardPage newDashboardPage; - private String grantSpecificPortalPermissionLink = "portalKitTestHelper/14DE09882B540AD5/grantSpecificPortalPermission.ivp?portalPermission=%s"; - private String denySpecificPortalPermissionLink = "portalKitTestHelper/14DE09882B540AD5/denySpecificPortalPermission.ivp?portalPermission=%s"; - - @Override - @Before - public void setup() { - super.setup(); - grantAccessFullListPermissions(); - newDashboardPage = new NewDashboardPage(); - } - - @After - public void tearDown() { - grantTaskActionsPermissions(); - grantAccessFullListPermissions(); - grantShowHideNotePermissions(); - grantDocumentOfInvolvedCaseWritePemissionToCurrentUser(); - grantCasePermissions(); - } - - @Test - public void testShowHideSubMenuItems() { - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - denyAccessFullListPermissions(); - Assert.assertFalse(mainMenuPage.isProcessesDisplayed()); - Assert.assertFalse(mainMenuPage.isTasksDisplayed()); - Assert.assertFalse(mainMenuPage.isCasesDisplayed()); - Assert.assertFalse(mainMenuPage.isStatisticsDisplayed()); - - grantAccessFullListPermissions(); - newDashboardPage = new NewDashboardPage(); - WaitHelper.assertTrueWithWait(() -> mainMenuPage.isProcessesDisplayed()); - Assert.assertTrue(mainMenuPage.isTasksDisplayed()); - Assert.assertTrue(mainMenuPage.isCasesDisplayed()); - Assert.assertTrue(mainMenuPage.isStatisticsDisplayed()); - } - - @Test - public void testShowHideTaskActions() { - denyTaskActionsPermissions(); - createTestingTasks(); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - Assert.assertFalse(taskWidgetPage.isTaskResetDisplayed()); - Assert.assertFalse(taskWidgetPage.isTaskDelegateDisplayed()); - Assert.assertFalse(taskWidgetPage.isTaskReserverDisplayed()); - Assert.assertFalse(taskWidgetPage.isAdhocSideStepDisplayed()); - - grantTaskActionsPermissions(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.sideStepMenuOnActionButton(0); - Assert.assertTrue(taskWidgetPage.isTaskResetDisplayed()); - Assert.assertTrue(taskWidgetPage.isTaskDelegateDisplayed()); - Assert.assertTrue(taskWidgetPage.isTaskReserverDisplayed()); - Assert.assertTrue(taskWidgetPage.isAdhocSideStepDisplayed()); - } - - @Test - public void testShowHideNoteAndDocumentButtons() { - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestingTasks(); - denyShowHideNotePermissions(); - denyDocumentOfInvolvedCaseWritePemissionFromCurrentUser(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage caseWidgetPage = mainMenuPage.openCaseList(); - CaseDetailsPage caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Leave Request"); - Assert.assertFalse(caseDetailsPage.isAddNoteButtonDisplayed()); - Assert.assertFalse(caseDetailsPage.isShowMoreNoteButtonDisplayed()); - Assert.assertFalse(caseDetailsPage.isAddDocumentLinkDisplayed()); - TaskWidgetPage taskWidgetPage = mainMenuPage.openTaskList(); - TaskDetailsPage taskDetailsPage = taskWidgetPage.openTaskDetails(0); - Assert.assertFalse(taskDetailsPage.isAddNoteButtonDisplayed()); - Assert.assertFalse(taskDetailsPage.isShowMoreNoteButtonDisplayed()); - Assert.assertFalse(taskDetailsPage.isAddDocumentLinkDisplayed()); - - grantShowHideNotePermissions(); - grantDocumentOfInvolvedCaseWritePemissionToCurrentUser(); - mainMenuPage.openCaseList(); - caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Leave Request"); - Assert.assertTrue(caseDetailsPage.isAddNoteButtonDisplayed()); - Assert.assertTrue(caseDetailsPage.isShowMoreNoteButtonDisplayed()); - Assert.assertTrue(caseDetailsPage.isAddDocumentLinkDisplayed()); - mainMenuPage.openTaskList(); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - Assert.assertTrue(taskDetailsPage.isAddNoteButtonDisplayed()); - Assert.assertTrue(taskDetailsPage.isShowMoreNoteButtonDisplayed()); - Assert.assertTrue(taskDetailsPage.isAddDocumentLinkDisplayed()); - } - - @Test - public void testShowHideLinkRelatedToCasePermissions() { - createTestingTasks(); - denyCasePermissions(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage caseWidgetPage = mainMenuPage.openCaseList(); - CaseDetailsPage caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Leave Request"); - Assert.assertFalse(caseDetailsPage.isShowDetailsDisplayed()); - - grantCasePermissions(); - mainMenuPage.openCaseList(); - caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Leave Request"); - caseDetailsPage.openActionMenu(); - Assert.assertTrue(caseDetailsPage.isShowDetailsDisplayed()); - } - - private void grantAccessFullListPermissions() { - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_PROCESS_LIST.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_CASE_LIST.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_TASK_LIST.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_STATISTICS_LIST.getValue())); - } - - private void denyAccessFullListPermissions() { - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_PROCESS_LIST.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_CASE_LIST.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_TASK_LIST.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.ACCESS_FULL_STATISTICS_LIST.getValue())); - } - - private void grantTaskActionsPermissions() { - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_RESET_ACTION.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_DELEGATE_ACTION.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_RESERVE_ACTION.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_ADDITIONAL_OPTIONS.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_DESTROY_ACTION.getValue())); - } - - private void denyTaskActionsPermissions() { - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_RESET_ACTION.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_DELEGATE_ACTION.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_RESERVE_ACTION.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_ADDITIONAL_OPTIONS.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_DISPLAY_DESTROY_ACTION.getValue())); - } - - private void grantCasePermissions() { - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.SHOW_CASE_DETAILS.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.SHOW_ALL_TASKS_OF_CASE.getValue())); - } - - private void denyCasePermissions() { - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.SHOW_CASE_DETAILS.getValue())); - } - - private void grantShowHideNotePermissions() { - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_CASE_ADD_NOTE.getValue())); - redirectToRelativeLink(String.format(grantSpecificPortalPermissionLink, PortalPermission.TASK_CASE_SHOW_MORE_NOTE.getValue())); - } - - private void denyShowHideNotePermissions() { - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.TASK_CASE_ADD_NOTE.getValue())); - redirectToRelativeLink(String.format(denySpecificPortalPermissionLink, PortalPermission.TASK_CASE_SHOW_MORE_NOTE.getValue())); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessChainTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessChainTest.java deleted file mode 100644 index 9a9da8f85f7..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessChainTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.ProcessChainPage; - -public class ProcessChainTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(processChainShowcaseUrl); - } - - @Test - public void testDisplayProcessChain() { - ProcessChainPage processChainPage = new ProcessChainPage(); - processChainPage.waitForPageLoaded(); - assertTrue(processChainPage.isEmptyNextStepButtonDisplay()); - } - - @Test - public void testNextStepActionProcessChain() { - ProcessChainPage processChainPage = new ProcessChainPage(); - processChainPage.waitForPageLoaded(); - assertEquals("Step 3", processChainPage.getCurrentStep()); - processChainPage.nextStep(); - assertEquals("Step 4", processChainPage.getCurrentStep()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessHistoryTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessHistoryTest.java deleted file mode 100644 index 2d38ed1a386..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessHistoryTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.ProcessHistoryPage; - -public class ProcessHistoryTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - } - - @Test - public void testDisplayProcessHistory() { - redirectToRelativeLink(createAlphaCompanyUrl); - redirectToRelativeLink(viewAlphaCompanyProcessHistoryUrl); - - ProcessHistoryPage processHistoryPage = new ProcessHistoryPage(); - processHistoryPage.waitForPageLoaded(); - assertEquals(1, processHistoryPage.countCases()); - } - - @Test - public void testDisplayProcessHistoryDialog() { - redirectToRelativeLink(createBetaCompanyUrl); - redirectToRelativeLink(viewBetaCompanyProcessHistoryInDialogUrl); - - ProcessHistoryPage processHistoryPage = new ProcessHistoryPage(); - processHistoryPage.waitForPageLoaded(); - assertEquals(1, processHistoryPage.openDialogAndCountCases()); - } - - @Test - public void testDisplayEmptyMessage() { - redirectToRelativeLink(viewAlphaCompanyProcessHistoryUrl); - ProcessHistoryPage processHistoryPage = new ProcessHistoryPage(); - processHistoryPage.waitForPageLoaded(); - assertTrue(processHistoryPage.isEmptyMessageDisplay()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessInformationTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessInformationTest.java deleted file mode 100644 index 39eef398271..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessInformationTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProcessInformationPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.TaskWidgetPage; - -public class ProcessInformationTest extends BaseTest { - - private NewDashboardPage newDashboardPage; - private ProcessWidgetPage processWidget; - private ProcessInformationPage processInformationPage; - private static String PROCESS_NAME = "Process With Process Steps"; - private static String PROCESS_DESCRIPTION = "Create task for a process with three process steps which can be show in Porcess Information page"; - - @Before - @Override - public void setup() { - super.setup(); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testStartProcessFromProcessInformationPage() { - navigateToProcessInformationPage(); - assertEquals(PROCESS_NAME, processInformationPage.getProcessName()); - assertEquals(PROCESS_DESCRIPTION, processInformationPage.getProcessDescription()); - - processInformationPage.startProcess(); - newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - taskWidget.filterTasksInExpandedModeBy(PROCESS_NAME, 1); - assertEquals(1, taskWidget.countTasks()); - } - - @Test - public void testBackToProcessListFromProcessInformationPage() { - navigateToProcessInformationPage(); - - processInformationPage.back(); - processWidget = new ProcessWidgetPage(); - assertTrue(processWidget.isDisplayed()); - } - - @Test - public void testBackToCaseDetailsFromProcessInformationPage() { - login(TestAccount.ADMIN_USER); - processWidget = NavigationHelper.navigateToProcessList(); - processWidget.startProcess(PROCESS_NAME); - - newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidget = newDashboardPage.openCaseList(); - CaseDetailsPage caseDetails = caseWidget.openCaseDetailsFromActionMenuByCaseName(PROCESS_NAME); - caseDetails.openActionMenu(); - caseDetails.openProcessOverviewPage(); - - processInformationPage = new ProcessInformationPage(); - assertEquals(PROCESS_NAME, processInformationPage.getProcessName()); - assertEquals(PROCESS_DESCRIPTION, processInformationPage.getProcessDescription()); - - processInformationPage.back(); - caseDetails = new CaseDetailsPage(); - assertEquals("Case Details", caseDetails.getPageTitle()); - assertEquals(PROCESS_NAME, caseDetails.getDescription()); - } - - private void navigateToProcessInformationPage() { - String processName = "Process With Process Steps"; - processWidget = NavigationHelper.navigateToProcessList(); - - processWidget.clickMoreInformationLink(processName); - processInformationPage = new ProcessInformationPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessViewerTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessViewerTest.java deleted file mode 100644 index 0e057a62a7b..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessViewerTest.java +++ /dev/null @@ -1,202 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProcessViewerComponentPage; -import portal.guitest.page.ProcessViewerPage; -import portal.guitest.page.TaskWidgetPage; - -public class ProcessViewerTest extends BaseTest { - - private static final String PROCESS_VIEWER_IS_FOUND_ON_TASK_LIST_PAGE = "Process Viewer is found on TaskList page"; - private static final String PROCESS_VIEWER_IS_FOUND_ON_TASK_DETAILS_PAGE = "Process Viewer is found on CaseDetails page"; - private static final String PROCESS_VIEWER_IS_FOUND_IN_CASE_LIST = "Process Viewer is found in CaseList"; - private static final String PROCESS_VIEWER_IS_FOUND_ON_CASE_DETAILS_PAGE = "Process Viewer is found on CaseDetails page"; - private static final String PROCESS_VIEWER_IS_NOT_FOUND_IN_CASE_LIST = "Process Viewer is NOT found in CaseList"; - private static final String PROCESS_VIEWER_IS_NOT_FOUND_ON_CASE_DETAILS_PAGE = "Process Viewer is NOT found on CaseDetails page"; - private static final String PROCESS_VIEWER_IS_NOT_FOUND_ON_TASK_LIST_PAGE = "Process Viewer is NOT found on TaskList page"; - private static final String PROCESS_VIEWER_IS_NOT_FOUND_ON_TASK_DETAILS_PAGE = "Process Viewer is NOT found on TaskDetails page"; - private static final String PROCESS_VIEWER = "Process Viewer"; - private NewDashboardPage newDashboardPage; - private CaseWidgetPage caseWidgetPage; - private TaskWidgetPage taskWidgetPage; - - @Override - @Before - public void setup() { - super.setup(); - } - - @Test - public void testOpenProcessViewerComponent() { - redirectToRelativeLink(processViewerExampleInFrameUrl); - ProcessViewerComponentPage processViewerPage = new ProcessViewerComponentPage(); - assertTrue(processViewerPage.getProcessRequestPath().equalsIgnoreCase("Leave Request")); - } - - @Test - public void testPermissionForProcessViewerComponent() { - redirectToRelativeLink(testProcessViewerPermissionUrl); - ProcessViewerPage processViewerPage = new ProcessViewerPage(); - assertTrue(processViewerPage.getErrorMessage().equalsIgnoreCase("You do not have the required permission to view this process.")); - } - - @Test - public void testOpenProcessViewerFromCase() { - createTestingTasks(); - gotoCaseList(); - caseWidgetPage.openActionStepMenu(); - caseWidgetPage.clickOnProcessViewerOption(); - WaitHelper.assertTrueWithWait(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - ProcessViewerPage processViewerPage = new ProcessViewerPage(); - assertTrue(processViewerPage.getProcessRequestPath().equalsIgnoreCase("Categoried Leave Request")); - } - - @Test - public void testOpenProcessViewerFromTask() { - createTestingTasks(); - gotoTaskList(); - taskWidgetPage.clickOnTaskActionLink(0); - taskWidgetPage.clickOnProcessViewerOption(); - WaitHelper.assertTrueWithWait(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - ProcessViewerPage processViewerPage = new ProcessViewerPage(); - assertTrue(processViewerPage.getProcessRequestPath().equalsIgnoreCase("Categoried Leave Request")); - } - - @Test - public void testCanSeeProcessViewerOptionInCaseAction() { - createTestingTasks(); - gotoCaseList(); - caseWidgetPage.openActionStepMenu(); - var steps = caseWidgetPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_IN_CASE_LIST, steps.contains(PROCESS_VIEWER)); - - var caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Leave Request"); - caseDetailsPage.openActionMenu(); - var detailPageSteps = caseDetailsPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_ON_CASE_DETAILS_PAGE, detailPageSteps.contains(PROCESS_VIEWER)); - } - - @Test - public void testNotShowProcessViewerForTechnicalCase() { - redirectToRelativeLink(createCaseWithTechnicalCaseUrl); - gotoCaseList(); - caseWidgetPage.openActionStepMenu(); - var steps = caseWidgetPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_IN_CASE_LIST, steps.contains(PROCESS_VIEWER)); - - var caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Order Pizza"); - caseDetailsPage.clickRelatedCaseActionButton(0); - var detailPageSteps = caseDetailsPage.getAvailableActionStepsOfTechnicalCase(0); - assertTrue(PROCESS_VIEWER_IS_FOUND_ON_CASE_DETAILS_PAGE, !detailPageSteps.contains(PROCESS_VIEWER)); - } - - @Test - public void testNotShowProcessViewerForExpressCase() { - login(TestAccount.ADMIN_USER); - var expressManagementTest = new ExpressManagementTest(); - expressManagementTest.prepareExpressWorkflowStep(); - expressManagementTest.executePromoteResourceTask(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - gotoCaseList(); - caseWidgetPage.openActionStepMenu(); - var steps = caseWidgetPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_FOUND_IN_CASE_LIST, !steps.contains(PROCESS_VIEWER)); - - var caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Request new Resources - Express process"); - caseDetailsPage.openActionMenu(); - var detailPageSteps = caseDetailsPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_FOUND_ON_CASE_DETAILS_PAGE, !detailPageSteps.contains(PROCESS_VIEWER)); - } - - @Test - public void testCanSeeProcessViewerInTaskAction() { - createTestingTasks(); - gotoTaskList(); - var actions = taskWidgetPage.getActiveTaskAction(0); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_ON_TASK_LIST_PAGE, actions.contains(PROCESS_VIEWER)); - taskWidgetPage.refresh(); - var taskDetailsPage = taskWidgetPage.openTaskDetailsFromActionMenu(0); - var detailActions = taskDetailsPage.getActiveTaskAction(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_ON_TASK_DETAILS_PAGE, detailActions.contains(PROCESS_VIEWER)); - } - - @Test - public void testProcessViewerPermissionInCaseAction() { - redirectToRelativeLink(processViewerPermissionExampleUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - gotoCaseList(); - caseWidgetPage.openActionStepMenu(); - var steps = caseWidgetPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_FOUND_IN_CASE_LIST, !steps.contains(PROCESS_VIEWER)); - - var caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Process Viewer Permission Example Case"); - caseDetailsPage.openActionMenu(); - var detailPageSteps = caseDetailsPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_FOUND_ON_CASE_DETAILS_PAGE, !detailPageSteps.contains(PROCESS_VIEWER)); - } - - @Test - public void testProcessViewerPermissionInTaskAction() { - redirectToRelativeLink(processViewerPermissionExampleUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - gotoTaskList(); - var actions = taskWidgetPage.getActiveTaskAction(0); - assertTrue(PROCESS_VIEWER_IS_FOUND_ON_TASK_LIST_PAGE, !actions.contains(PROCESS_VIEWER)); - taskWidgetPage.refresh(); - var taskDetailsPage = taskWidgetPage.openTaskDetailsFromActionMenu(0); - var detailActions = taskDetailsPage.getActiveTaskAction(); - assertTrue(PROCESS_VIEWER_IS_FOUND_ON_TASK_DETAILS_PAGE, !detailActions.contains(PROCESS_VIEWER)); - } - - @Test - public void testCaseMapViewerPermissionInCaseAction() { - redirectToRelativeLink(createTestingCaseMapUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - gotoCaseList(); - caseWidgetPage.openActionStepMenu(); - var steps = caseWidgetPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_IN_CASE_LIST, steps.contains(PROCESS_VIEWER)); - - var caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Business Case Map: Leave Request"); - caseDetailsPage.openActionMenu(); - var detailPageSteps = caseDetailsPage.getAvailableActionSteps(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_ON_CASE_DETAILS_PAGE, detailPageSteps.contains(PROCESS_VIEWER)); - } - - @Test - public void testCaseMapViewerPermissionInTaskAction() { - redirectToRelativeLink(createTestingCaseMapUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - gotoTaskList(); - var actions = taskWidgetPage.getActiveTaskAction(0); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_ON_TASK_LIST_PAGE, actions.contains(PROCESS_VIEWER)); - taskWidgetPage.refresh(); - var taskDetailsPage = taskWidgetPage.openTaskDetailsFromActionMenu(0); - var detailActions = taskDetailsPage.getActiveTaskAction(); - assertTrue(PROCESS_VIEWER_IS_NOT_FOUND_ON_TASK_DETAILS_PAGE, detailActions.contains(PROCESS_VIEWER)); - } - - private CaseWidgetPage gotoCaseList() { - newDashboardPage = new NewDashboardPage(); - var mainMenuPage = newDashboardPage.openMainMenu(); - caseWidgetPage = mainMenuPage.selectCaseMenu(); - return caseWidgetPage; - } - - private void gotoTaskList() { - newDashboardPage = new NewDashboardPage(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessWidgetTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessWidgetTest.java deleted file mode 100644 index 011d3c72f0d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProcessWidgetTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.concurrent.TimeUnit; - -import org.junit.Before; -import org.junit.Test; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProcessWidgetPage; -import portal.guitest.page.ProcessWidgetPage.AddNewExternalLinkDialog; - -public class ProcessWidgetTest extends BaseTest { - - private static final String CASE_MAP_LEAVES = "Case Map: Leave Request"; - private static final String AGOOGLE_LINK = "AGoogle"; - - private NewDashboardPage newDashboardPage; - ProcessWidgetPage processWidget; - - @Before - @Override - public void setup() { - super.setup(); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testCaseMapIsDisplayedInExpandedMode() { - processWidget = NavigationHelper.navigateToProcessList(); - assertNotNull(processWidget.getProcess(CASE_MAP_LEAVES)); - resetLanguageOfCurrentUser(); - } - - @Test - public void testDeleteProcess() { - String processName = "AGoogle"; - String processLink = "google.com"; - processWidget = NavigationHelper.navigateToProcessList(); - createPrivateExternalTestProcess(processName, processLink); - processWidget = NavigationHelper.navigateToProcessList(); - processWidget.selectViewMode(ProcessWidgetPage.GRID_MODE); - processWidget.waitForGridProcessListDisplayed(); - processWidget.clickMoreButtonOfFirstGridProcess(); - processWidget.deleteGridProcess(0); - resetLanguageOfCurrentUser(); - } - - @Test - // May not run on IE version 11.0.20 or later due to Selenium. - public void testOpenExternalProcessInNewTab() { - String processName = "AGoogle"; - String processLink = "google.com"; - processWidget = NavigationHelper.navigateToProcessList(); - createPrivateExternalTestProcess(processName, processLink); - assertEquals(1, newDashboardPage.countBrowserTab()); - - processWidget.startProcess(AGOOGLE_LINK); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> newDashboardPage.getPageTitle().length() > 1); - assertEquals("Google", newDashboardPage.getPageTitle()); - resetLanguageOfCurrentUser(); - } - - @Test - public void testBreadCrumb() { - processWidget = NavigationHelper.navigateToProcessList(); - assertEquals("Processes", processWidget.getTextOfCurrentBreadcrumb()); - - processWidget.goToHomeFromBreadcrumb(); - newDashboardPage = new NewDashboardPage(); - assertEquals(true, newDashboardPage.isDisplayed()); - resetLanguageOfCurrentUser(); - } - - private void createPrivateExternalTestProcess(String processName, String processLink) { - AddNewExternalLinkDialog addNewExternalLinkDialog = processWidget.openNewExternalLinkDialog(); - addNewExternalLinkDialog.inputDataForPrivateExternalLink(processName, processLink); - addNewExternalLinkDialog.submitForm(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProjectVersionTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProjectVersionTest.java deleted file mode 100644 index 9bddea5128c..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ProjectVersionTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.ProjectVersionPage; - -public class ProjectVersionTest extends BaseTest { - - @Test - public void shouldShowProjectVersion() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - ProjectVersionPage projectVersionPage = newDashboardPage.openProjectVersionPage(); - assertTrue("Engine version not displayed", projectVersionPage.isEngineVersionDisplayed()); - assertTrue("Portal version not displayed", projectVersionPage.isPortalVersionDisplayed()); - assertTrue("First project version not displayed", projectVersionPage.isFirstProjectDisplayed()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleManagementTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleManagementTest.java deleted file mode 100644 index 039bb314fff..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleManagementTest.java +++ /dev/null @@ -1,183 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; - -import ch.ivy.addon.portalkit.enums.PortalPermission; -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.AdminSettingsPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.RoleManagementPage; - -public class RoleManagementTest extends BaseTest { - - private static final String DENY_SPECIFIC_PERMISSION = "portalKitTestHelper/14DE09882B540AD5/denySpecificPortalPermission.ivp?portalPermission=%s"; - private static final String GRANT_SPECIFIC_PERMISSION = "portalKitTestHelper/14DE09882B540AD5/grantSpecificPortalPermission.ivp?portalPermission=%s"; - - private NewDashboardPage newDashboardPage; - private AdminSettingsPage adminSettingsPage; - private RoleManagementPage roleManagementPage; - - @Before - @Override - public void setup() { - super.setup(); - login(TestAccount.ADMIN_USER); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testVisibilityForRoleManagementTab() { - accessToRoleManagement(); - assertTrue("RoleManagement tab is not displayed", roleManagementPage.isDisplayed()); - - // Admin lacks RoleReadAll permission - denySpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - newDashboardPage = new NewDashboardPage(); - adminSettingsPage = newDashboardPage.openAdminSettings(); - assertFalse("RoleManagement tab is displayed", adminSettingsPage.isRoleAssingmentTabViewPresent()); - } - - @Test - public void testVisibilityForCreatingRoleButton() { - grantSpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - accessToRoleManagement(); - assertTrue("Create role button is not displayed", roleManagementPage.isCreateNewRoleButtonPresent()); - roleManagementPage.openRoleCreationDialog(); - assertTrue("Role info dialog is not displayed", roleManagementPage.getRoleInfoDialogContent().isDisplayed()); - roleManagementPage.clickOnCancelLinkOfRoleDialog(); - - // Admin lacks RoleCreate permission - redirectToRelativeLink(String.format(DENY_SPECIFIC_PERMISSION, "RoleCreate")); - accessToRoleManagement(); - assertFalse("Create role button is displayed", roleManagementPage.isCreateNewRoleButtonPresent()); - } - - @Test - public void testVisibilityForDeletingRoleAction() { - grantSpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleCreate")); - var roleName = "NewRole" + UUID.randomUUID(); - RoleManagementPage roleManagementPage = accessToRoleManagementAndCreateNewRole(roleName); - assertTrue("New Role is not appear on tree", roleManagementPage.getRoleNamesInRoleTreeTable().contains(roleName)); - var deleteLinkClasses = roleManagementPage.getDeleteActionEnableForRole(roleName).getAttribute("class"); - assertFalse("User can not click on delele New Role", deleteLinkClasses.contains("ui-state-disabled")); - - // Admin lacks RoleDelete permission - redirectToRelativeLink(String.format(DENY_SPECIFIC_PERMISSION, "RoleDelete")); - accessToRoleManagement(); - assertTrue("RoleManagement tab is not displayed", roleManagementPage.isDisplayed()); - deleteLinkClasses = roleManagementPage.getDeleteActionEnableForRole(roleName).getAttribute("class"); - assertTrue("User can click on delele New Role", - deleteLinkClasses.contains("ui-state-disabled action-column-icon-button")); - - // Admin can delete role - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleDelete")); - accessToRoleManagement(); - assertTrue("RoleManagement tab is not displayed", roleManagementPage.isDisplayed()); - assertTrue("New Role is not appear on tree", roleManagementPage.getRoleNamesInRoleTreeTable().contains(roleName)); - roleManagementPage.deleteRole(roleName); - assertFalse("New Role still appears on tree", roleManagementPage.getRoleNamesInRoleTreeTable().contains(roleName)); - } - - @Test - public void testVisibilityForEditingRoleAction() { - grantSpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleCreate")); - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleDelete")); - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleMove")); - - var roleName = "NewRole" + UUID.randomUUID(); - roleManagementPage = accessToRoleManagementAndCreateNewRole(roleName); - assertTrue("New Role is not appear on tree", roleManagementPage.getRoleNamesInRoleTreeTable().contains(roleName)); - - // Admin lacks RoleCreate permission then he cannot edit role - redirectToRelativeLink(String.format(DENY_SPECIFIC_PERMISSION, "RoleCreate")); - accessToRoleManagement(); - var editLinkClasses = roleManagementPage.getEditActionEnableForRole(roleName).getAttribute("class"); - assertTrue("User can click on edit New Role", - editLinkClasses.contains("ui-state-disabled action-column-icon-button")); - - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleCreate")); - accessToRoleManagement(); - assertTrue("RoleManagement tab is not displayed", roleManagementPage.isDisplayed()); - editLinkClasses = roleManagementPage.getEditActionEnableForRole(roleName).getAttribute("class"); - assertFalse("User can not click on edit New Role", editLinkClasses.contains("ui-state-disabled")); - roleManagementPage.clickOnEditRole(roleName); - var roleDisplayName = "RoleDisplayName is edited"; - roleManagementPage.enterRoleAdditionalInformation(roleDisplayName, "RoleDescription is edited"); - roleManagementPage.clickOnSaveRoleButtonDialog(); - assertTrue("New Role is not appears on tree", roleManagementPage.getRoleNamesInRoleTreeTable().contains(roleName)); - assertTrue("RoleDisplayname is not be changed", - roleManagementPage.getRoleDisplayNameInRoleTreeTable().contains(roleDisplayName)); - } - - @Test - public void testVisibilityForAssigningUsersAction() { - grantSpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleCreate")); - var roleName = "NewRole" + UUID.randomUUID(); - RoleManagementPage roleManagementPage = accessToRoleManagementAndCreateNewRole(roleName); - assertTrue("New Role is not appear on tree", roleManagementPage.getRoleNamesInRoleTreeTable().contains(roleName)); - var totalUsers = roleManagementPage.getTotalUsersOfRoleInRoleTreeTable(roleName); - var assignUsersLinkClasses = roleManagementPage.getAssigningUsersActionEnableForRole(roleName).getAttribute("class"); - assertFalse("User can not click on AssignUsers", assignUsersLinkClasses.contains("ui-state-disabled")); - roleManagementPage.assignUsersToRole(roleName, Arrays.asList("demo", "david")); - roleManagementPage.clickOnCloseAssignUsersButton(); - assertFalse("Total users of role is the same", - totalUsers.equalsIgnoreCase(roleManagementPage.getTotalUsersOfRoleInRoleTreeTable(roleName))); - } - - @Test - public void testAssigningUsersToExistedRole() { - grantSpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - redirectToRelativeLink(String.format(GRANT_SPECIFIC_PERMISSION, "RoleCreate")); - accessToRoleManagement(); - var roleName = "HR"; - var assignUsersLinkClasses = - roleManagementPage.getAssigningUsersActionEnableForRole(roleName).getAttribute("class"); - assertFalse("User can not click on AssignUsers", assignUsersLinkClasses.contains("ui-state-disabled")); - roleManagementPage.removeAllUsersOfRole(roleName); - roleManagementPage.clickOnCloseAssignUsersButton(); - var totalUsers = roleManagementPage.getTotalUsersOfRoleInRoleTreeTable(roleName); - roleManagementPage.assignUsersToRole(roleName, Arrays.asList("admin", "demo", "david")); - roleManagementPage.clickOnCloseAssignUsersButton(); - assertFalse("Total users of role is the same", - totalUsers.equalsIgnoreCase(roleManagementPage.getTotalUsersOfRoleInRoleTreeTable(roleName))); - } - - @Test - public void testFilteringRoles() { - grantSpecificPortalPermission(PortalPermission.ROLE_MANAGEMENT); - accessToRoleManagement(); - var roleName = "HR"; - roleManagementPage.filterRoleTreeTableByRoleName(roleName); - assertTrue("Role tree does not contain (Everybody);(HR)", - roleManagementPage.getRoleNamesInRoleTreeTable().equalsIgnoreCase("Everybody;HR")); - } - - private RoleManagementPage accessToRoleManagementAndCreateNewRole(String roleName) { - accessToRoleManagement(); - roleManagementPage.openRoleCreationDialog(); - roleManagementPage.createNewRoleWithData("Everybody", roleName, "New Role", "NewRoleDescription", - Arrays.asList("admin")); - roleManagementPage.clickOnSaveRoleButtonDialog(); - return roleManagementPage; - } - - private RoleManagementPage accessToRoleManagement() { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - var adminSettingsPage = new NewDashboardPage().openAdminSettings(); - assertTrue("RoleManagement tab is NOT displayed", adminSettingsPage.isRoleAssingmentTabViewPresent()); - roleManagementPage = adminSettingsPage.openRoleManagementTab(); - return roleManagementPage; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleSelectionComponentTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleSelectionComponentTest.java deleted file mode 100644 index 2a4e60bdf77..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/RoleSelectionComponentTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.RoleSelectionComponentPage; - -public class RoleSelectionComponentTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(roleSelectionComponentShowcaseUrl); - } - - @Test - public void testDefaultRoleSelectionComponent() { - RoleSelectionComponentPage roleSelectionComponentPage = new RoleSelectionComponentPage(); - String value = roleSelectionComponentPage.selectFirstItemForDefaultRoleSelectionComponent("Backend Developer"); - assertEquals(value, roleSelectionComponentPage.getDefaultRoleSelection()); - } - - @Test - public void testRoleFromDefinedRoleSelectionComponent() { - RoleSelectionComponentPage roleSelectionComponentPage = new RoleSelectionComponentPage(); - String value = roleSelectionComponentPage.selectFirstItemForRoleFromDefinedRoleSelectionComponent("Backend Developer"); - assertEquals(value, roleSelectionComponentPage.getRoleFromDefinedRoleSelection()); - } - - @Test - public void testFloatingLabelAndExcludeRoleSelection() { - RoleSelectionComponentPage roleSelectionComponentPage = new RoleSelectionComponentPage(); - String value = roleSelectionComponentPage.selectFirstItemForFloatingLabelAndExcludeRoleSelectionComponent("Backend Developer"); - assertEquals(value, roleSelectionComponentPage.getFloatingLabelAndExcludeRoleSelection()); - } - - @Test - public void testAjaxEventRoleSelection() { - RoleSelectionComponentPage roleSelectionComponentPage = new RoleSelectionComponentPage(); - String value = roleSelectionComponentPage.selectFirstItemForAjaxEventRoleSelectionComponent("Backend Developer"); - assertEquals(value, roleSelectionComponentPage.getAjaxEventRoleSelection()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchCaseTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchCaseTest.java deleted file mode 100644 index 3bad9f5efc0..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchCaseTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.SearchResultPage; -import portal.guitest.page.TemplatePage.GlobalSearch; - -public class SearchCaseTest extends BaseTest { - - private NewDashboardPage newDashboardPage; - - @Before - @Override - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - redirectToRelativeLink("internalSupport/14B2FC03D2E87141/CreateTaskWithSpecialCharacter.ivp"); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testFindCaseByNameAndOpenCaseList() { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - assertTrue(globalSearch.isDisplayed()); - - String caseName = "Leave Request"; - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(caseName); - searchResultPage.waitForFirstTabFinishedLoading(); - searchResultPage.openCaseTab(); - assertEquals(caseName, searchResultPage.getCaseResult(0)); - assertTrue(searchResultPage.isCaseCategoryColumnDisplayed()); - } - - @Test - public void testFindCaseByNameWithSpecialCharacter() { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - assertTrue(globalSearch.isDisplayed()); - - String caseName = "\u00D6sterreich Resource with ID 1212"; - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(caseName); - searchResultPage.openCaseTab(); - assertEquals(caseName, searchResultPage.getCaseResult(0)); - } - - @Test - public void testFindNotFoundOutData() { - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - assertTrue(globalSearch.isDisplayed()); - - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword("no case found"); - searchResultPage.openCaseTab(); - assertTrue(searchResultPage.isCaseResultEmpty()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchProcessTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchProcessTest.java deleted file mode 100644 index ca5130079ec..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchProcessTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.SearchResultPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.TemplatePage.GlobalSearch; - -public class SearchProcessTest extends BaseTest { - - private NewDashboardPage newDashboardPage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testFindAndStartProcessByName() { - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - assertTrue(globalSearch.isDisplayed()); - - String processName = "Simple Payment"; - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(processName); - searchResultPage.waitForFirstTabFinishedLoading(); - assertEquals(processName, searchResultPage.getProcessResult(processName)); - assertTrue(searchResultPage.isProcessGroupDisplay("S")); - - searchResultPage.startProcess(processName); - newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - WaitHelper.assertTrueWithRefreshPage(taskWidgetPage, - () -> taskWidgetPage.getNameOfTaskAt(0).contains("Payment")); - } - - @Test - public void testFindCaseMapByName() { - String caseMapName = "Case Map: Leave Request"; - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - assertTrue(globalSearch.isDisplayed()); - - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(caseMapName); - searchResultPage.waitForFirstTabFinishedLoading(); - assertEquals(caseMapName, searchResultPage.getProcessResult(caseMapName)); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchTaskTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchTaskTest.java deleted file mode 100644 index ceb0bc32b5d..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SearchTaskTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.SearchResultPage; -import portal.guitest.page.TemplatePage.GlobalSearch; - -public class SearchTaskTest extends BaseTest { - private NewDashboardPage newDashboardPage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - newDashboardPage = new NewDashboardPage(); - } - - @Test - public void testFindTaskByName() { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - GlobalSearch globalSearch = newDashboardPage.getGlobalSearch(); - assertTrue(globalSearch.isDisplayed()); - - String taskName = "Annual Leave Request"; - SearchResultPage searchResultPage = globalSearch.inputSearchKeyword(taskName); - searchResultPage.openTaskTab(); - assertEquals(taskName, searchResultPage.getTaskResult(0)); - assertTrue(searchResultPage.isTaskCategoryColumnDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowCaseNoteHistoryTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowCaseNoteHistoryTest.java deleted file mode 100644 index b8bdc25c822..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowCaseNoteHistoryTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Before; -import org.junit.Test; - -import ch.ivy.addon.portalkit.enums.PortalPermission; -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.NoteHistoryPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class ShowCaseNoteHistoryTest extends BaseTest { - - private CaseDetailsPage detailsPage; - private NewDashboardPage newDashboardPage; - private MainMenuPage mainMenuPage; - private NoteHistoryPage caseHistoryPage; - private static final String NOTE_CONTENT = "test"; - private static final String CASE_NAME = "Leave Request"; - private static final String CASE_STATUS = "Open"; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - } - - @Test - public void testShowCaseNoteHistory() { - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName(CASE_NAME); - String caseName = detailsPage.getCaseName(); - String caseId = detailsPage.getCaseId(); - String uuid = detailsPage.getCaseUuid(); - detailsPage.addNote(NOTE_CONTENT); - goToCaseNoteHistoryPage(uuid); - - caseHistoryPage = new NoteHistoryPage(); - int numberOfNotes = caseHistoryPage.countNotes(); - assertEquals(2, numberOfNotes); - assertEquals(NOTE_CONTENT, caseHistoryPage.getNoteContentOfRow(0)); - assertEquals(caseName, caseHistoryPage.getCaseName()); - assertEquals(caseId, caseHistoryPage.getCaseId()); - assertTrue(StringUtils.equalsIgnoreCase(CASE_STATUS, caseHistoryPage.getCaseState())); - } - - @Test - public void testShowCaseNoteHistoryInTask() { - grantSpecificPortalPermission(PortalPermission.TASK_CASE_ADD_NOTE); - CaseWidgetPage caseWidgetPage = NavigationHelper.navigateToCaseList(); - CaseDetailsPage caseDetailsPage = caseWidgetPage.openDetailsOfCaseHasName("Leave Request"); - String caseUuid = caseDetailsPage.getCaseUuid(); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - taskTemplatePage.openCaseInfo(); - taskTemplatePage.addNewNote(NOTE_CONTENT); - String caseName = taskTemplatePage.getCaseName(); - getBrowser().getDriver().switchTo().defaultContent(); - goToCaseNoteHistoryPage(caseUuid); - - caseHistoryPage = new NoteHistoryPage(); - int numberOfNotes = caseHistoryPage.countNotes(); - assertEquals(2, numberOfNotes); - assertEquals(NOTE_CONTENT, caseHistoryPage.getNoteContentOfRow(0)); - assertEquals(caseName, caseHistoryPage.getCaseName()); - assertTrue(StringUtils.equalsIgnoreCase(CASE_STATUS, caseHistoryPage.getCaseState())); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowRelatedTasksTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowRelatedTasksTest.java deleted file mode 100644 index ad545960785..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowRelatedTasksTest.java +++ /dev/null @@ -1,115 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.TimeUnit; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.openqa.selenium.TimeoutException; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NoteHistoryPage; -import portal.guitest.page.TaskDetailsPage; - -public class ShowRelatedTasksTest extends BaseTest { - - private CaseDetailsPage detailsPage; - private NewDashboardPage newDashboardPage; - NoteHistoryPage caseHistoryPage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink("portalKitTestHelper/153CACC26D0D4C3D/createRelatedTasksTestUser.ivp"); - redirectToRelativeLink(createTestingTasksUrl); - login(TestAccount.TEST_RELATED_TASKS_USER); - denyReadAllPermissionFromCurrentUser(); - } - - private void openCaseDetail() { - newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - detailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - } - - @Test - public void testRelatedTasksWithTaskReadAllPermission() { - grantTaskReadAllPermissionsToCurrentUser(); - openCaseDetail(); - int numberOfTasks = detailsPage.countRelatedTasks(); - assertTrue(numberOfTasks == 4); - assertTrue(detailsPage.hasDoneTask()); - } - - @Test - public void testRelatedTasksWithTaskReadOwnCaseTasksPermission() { - grantTaskReadOwnCaseTaskPermissionsToCurrentUser(); - openCaseDetail(); - int numberOfTasks = detailsPage.countRelatedTasks(); - assertTrue(numberOfTasks == 4); - assertTrue(detailsPage.hasDoneTask()); - } - - @Test - public void testRelatedTasksWithNoPermission() { - denyReadAllPermissionFromCurrentUser(); - openCaseDetail(); - int numberOfTasks = detailsPage.countRelatedTasks(); - assertTrue(numberOfTasks == 2); - assertFalse(detailsPage.hasDoneTask()); - } - - @Test - public void testRelatedTasksWhenClickingRelatedTask() { - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - grantTaskReadOwnCaseTaskPermissionsToCurrentUser(); - openCaseDetail(); - detailsPage.clickRelatedTaskColumnsButton(); - detailsPage.clickRelatedTaskDefaultCheckbox(); - detailsPage.clickRelatedTaskColumnCheckbox(4); - detailsPage.clickRelatedTaskColumnCheckbox(5); - detailsPage.clickRelatedTaskColumnCheckbox(6); - detailsPage.clickRelatedTaskApplyButton(); - WaitHelper.assertTrueWithWait(() -> detailsPage.isRelatedTaskListColumnExist("related-task-name-column")); - TaskDetailsPage taskDetailsPage = detailsPage.openTasksOfCasePage("Sick Leave Request"); - assertEquals("Task Details", taskDetailsPage.getPageTitle()); - } - - @Test - @Ignore - public void testRelatedTasksWhenClickingDoneTask() { - grantTaskReadOwnCaseTaskPermissionsToCurrentUser(); - openCaseDetail(); - detailsPage.addNote("test"); - String doneTaskName = detailsPage.openDoneTask(0); - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> newDashboardPage.countBrowserTab() > 1); - newDashboardPage.switchLastBrowserTab(); - int numberOfNotes; - try { - numberOfNotes = caseHistoryPage.countNotes(); - } catch (TimeoutException e) { // sometimes session is destroyed (don't know reason why!!!) so we cannot reach the page - System.out.println("Stop testShowCaseNoteHistory test here because session is destroyed"); - return ; - } - assertEquals(2, numberOfNotes); - assertEquals("test", caseHistoryPage.getNoteContentOfRow(0)); - assertEquals("Task is done: " + doneTaskName, caseHistoryPage.getNoteContentOfRow(1)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowTaskNoteHistoryTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowTaskNoteHistoryTest.java deleted file mode 100644 index 2a632bb9fe0..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/ShowTaskNoteHistoryTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.NoteHistoryPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class ShowTaskNoteHistoryTest extends BaseTest { - - private static final String NOTE_CONTENT = "test"; - private NoteHistoryPage taskHistoryPage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - } - - @Test - public void testShowTaskNoteHistory() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskWidgetPage = newDashboardPage.openTaskList(); - TaskDetailsPage taskDetailsPage = taskWidgetPage.openTaskDetailsFromActionMenu(0); - String taskUuid = taskDetailsPage.getTaskUuid(); - NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - taskTemplatePage.openCaseInfo(); - taskTemplatePage.addNewNote(NOTE_CONTENT); - - goToTaskNoteHistoryPage(taskUuid); - taskHistoryPage = new NoteHistoryPage(); - int numberOfNotes = taskHistoryPage.countNotes(); - - assertEquals(1, numberOfNotes); - assertEquals(NOTE_CONTENT, taskHistoryPage.getNoteContentOfRow(0)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SideStepTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SideStepTest.java deleted file mode 100644 index 0db1ffe91ac..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SideStepTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.AdhocPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class SideStepTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingCaseMapUrl); - } - - @Test - @Ignore - public void testSideSteps() { - TaskTemplatePage taskTemplatePage = startATask(); - taskTemplatePage.clickTaskActionMenu(); - assertEquals(2, taskTemplatePage.countSideSteps()); - } - - private TaskTemplatePage startATask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - return taskTemplatePage; - } - - @Test - @Ignore - public void testAddAdhocTask() { - int firstTask = 0; - final String TASK_NAME = "Create Leave Request"; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidgetPage.countTasks() == 1); - assertEquals(taskWidgetPage.getNameOfTaskAt(0), TASK_NAME); - AdhocPage adhocPage = taskWidgetPage.addAdhoc(firstTask); - adhocPage.enterSubject("Collect Information"); - adhocPage.addTask(); - taskWidgetPage = adhocPage.startWorkflow(); - assertTrue(taskWidgetPage.countTasks() == 1); - assertEquals(taskWidgetPage.getNameOfTaskAt(0), "TASK Collect Information"); - taskWidgetPage.startTask(0); - adhocPage = new AdhocPage(); - adhocPage.addComment("Annual leaves are available"); - taskWidgetPage = adhocPage.send(); - assertTrue(taskWidgetPage.countTasks() == 1); - assertEquals(taskWidgetPage.getNameOfTaskAt(0), TASK_NAME); - } - - @Test - public void testSideStepInCaseList() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - int sideSteps = casePage.countSideStepItems(); - assertEquals(2, sideSteps); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/StatisticWidgetTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/StatisticWidgetTest.java deleted file mode 100644 index bd397b8861a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/StatisticWidgetTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static portal.guitest.page.StatisticWidgetPage.CASES_BY_CATEGORY_CHART_NAME; -import static portal.guitest.page.StatisticWidgetPage.CASE_BY_FINISHED_TASK_CHART_NAME; -import static portal.guitest.page.StatisticWidgetPage.CASE_BY_FINISHED_TIME_CHART_NAME; -import static portal.guitest.page.StatisticWidgetPage.CASE_BY_STATE_CHART_NAME; -import static portal.guitest.page.StatisticWidgetPage.ELAPSED_TIME_CHART_NAME; -import static portal.guitest.page.StatisticWidgetPage.TASK_BY_EXPIRY_CHART_NAME; -import static portal.guitest.page.StatisticWidgetPage.TASK_BY_PRIORITY_CHART_NAME; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.Sleeper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.StatisticWidgetPage; -import portal.guitest.page.UserProfilePage; - -public class StatisticWidgetTest extends BaseTest { - private static final String TASK_BY_PRIORITY_DEFAULT_CHART_NAME = "Tasks by Priority"; - - - private NewDashboardPage newDashboardPage; - private StatisticWidgetPage statisticWidgetPage; - private MainMenuPage mainMenuPage; - - @Override - @Before - public void setup() { - super.setup(); - Sleeper.sleep(2000); // To make Firefox test more stable, make business data updated correctly - redirectToRelativeLink(createTestingTasksUrl); - login(TestAccount.ADMIN_USER); - newDashboardPage = new NewDashboardPage(); - } - - @After - public void clear() { - resetLanguageOfCurrentUser(); - } - - @Test - public void testNavigateToChartFromMenu() { - grantPermissionToCreateChart(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.waitForElementDisplayed(By.id("statistics-widget:widget-container"), true); - assertTrue(statisticWidgetPage.isFullMode()); - } - - @Test - public void testNavigateToChartWithoutPermissionFromMenu() { - String denyPortalPermissionsURL = "portalKitTestHelper/14DE09882B540AD5/denyPortalPermission.ivp"; - redirectToRelativeLink(denyPortalPermissionsURL); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - assertEquals(false, statisticWidgetPage.hasCreateChartsLink()); - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantPortalPermission.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - @Test - public void testCreateCharts() { - grantPermissionToCreateChart(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.waitForElementDisplayed(By.id("statistics-widget:widget-container"), true); - statisticWidgetPage.switchCreateMode(); - - statisticWidgetPage.createTaskByPriorityChart(); - statisticWidgetPage.createTaskByExpiryChart(); - statisticWidgetPage.createCaseByStateChart(); - statisticWidgetPage.createElapsedTimeChart(); - statisticWidgetPage.createCaseByFinishedTask(); - statisticWidgetPage.createCaseByFinishTime(); - statisticWidgetPage.createCasesByCategory(); - - statisticWidgetPage.backToDashboard(); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='0:chart-name-container'] .chart-name").getText().equals(TASK_BY_PRIORITY_DEFAULT_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='1:chart-name-container'] .chart-name").getText().equals(TASK_BY_PRIORITY_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='2:chart-name-container'] .chart-name").getText().equals(TASK_BY_EXPIRY_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='3:chart-name-container'] .chart-name").getText().equals(CASE_BY_STATE_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='4:chart-name-container'] .chart-name").getText().equals(ELAPSED_TIME_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='5:chart-name-container'] .chart-name").getText().equals(CASE_BY_FINISHED_TASK_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='6:chart-name-container'] .chart-name").getText().equals(CASE_BY_FINISHED_TIME_CHART_NAME)); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='7:chart-name-container'] .chart-name").getText().equals(CASES_BY_CATEGORY_CHART_NAME)); - } - - @Test - public void testBreadCrumb() { - grantPermissionToCreateChart(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.waitForElementDisplayed(By.id("statistics-widget:widget-container"), true); - assertEquals("Statistics", statisticWidgetPage.getTextOfCurrentBreadcrumb()); - - statisticWidgetPage.switchCreateMode(); - assertEquals("Statistics", statisticWidgetPage.getTextOfCurrentBreadcrumb()); - - statisticWidgetPage.goToHomeFromBreadcrumb(); - newDashboardPage = new NewDashboardPage(); - assertEquals(true, newDashboardPage.isDisplayed()); - } - - private void grantPermissionToCreateChart() { - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantPortalPermission.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - @Test - public void testChartNameMultiLanguage() { - resetLanguageOfCurrentUser(); - grantPermissionToCreateChart(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.waitForElementDisplayed(By.id("statistics-widget:widget-container"), true); - - statisticWidgetPage.switchCreateMode(); - statisticWidgetPage.createTaskByPriorityChartMultiLanguage(); - - statisticWidgetPage.backToDashboard(); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='1:chart-name-container'] .chart-name").getText().equals("Task by priority chart English")); - - UserProfilePage userProfilePage = statisticWidgetPage.openMyProfilePage(); - userProfilePage.selectLanguage(3); - newDashboardPage = userProfilePage.save(); - - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - WaitHelper.assertTrueWithWait(() -> statisticWidgetPage.findElementByCssSelector("div[id$='1:chart-name-container'] .chart-name").getText().equals("Task by priority chart German")); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemNoteVisibilityTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemNoteVisibilityTest.java deleted file mode 100644 index 8c8c595d0ea..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemNoteVisibilityTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package portal.guitest.test; - -import static portal.guitest.common.Variable.HIDE_SYSTEM_NOTES_FROM_HISTORY; -import static portal.guitest.common.Variable.HIDE_SYSTEM_NOTES_FROM_HISTORY_ADMINISTRATOR; -import static portal.guitest.common.Variable.HIDE_SYSTEM_TASKS_FROM_HISTORY; -import static portal.guitest.common.Variable.HIDE_SYSTEM_TASKS_FROM_HISTORY_ADMINISTRATOR; - -import java.util.List; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.NoteHistoryPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; - -public class SystemNoteVisibilityTest extends BaseTest { - - private static final String CREATE_TESTING_TASK_URL = "internalSupport/14B2FC03D2E87141/processWithSystemNote.ivp"; - private static final String SYSTEM_USER_NAME = "System user"; - - @Override - @Before - public void setup() { - super.setup(); - //hide all system task in history to avoid effecting to test assertion - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - updatePortalSetting(HIDE_SYSTEM_TASKS_FROM_HISTORY.getKey(), "true"); - updatePortalSetting(HIDE_SYSTEM_TASKS_FROM_HISTORY_ADMINISTRATOR.getKey(), "true"); - redirectToRelativeLink(CREATE_TESTING_TASK_URL); - } - - @Test - public void testSystemNoteVisibilityInCaseForAdmin() { - login(TestAccount.ADMIN_USER); - - CaseDetailsPage caseDetailsPage = openCaseDetails(); - String caseId = caseDetailsPage.getCaseUuid(); - List caseNoteAuthors = caseDetailsPage.getCaseNoteAuthors(); - Assert.assertTrue(caseNoteAuthors.contains(SYSTEM_USER_NAME)); - - NoteHistoryPage caseNoteHistoryPage = openCaseNoteHistory(caseId); - caseNoteAuthors = caseNoteHistoryPage.getNoteAuthors(); - Assert.assertTrue(caseNoteAuthors.contains(SYSTEM_USER_NAME)); - } - - @Test - public void testSystemNoteVisibilityInCaseForNormalUser() { - CaseDetailsPage caseDetailsPage = openCaseDetails(); - String caseId = caseDetailsPage.getCaseUuid(); - List caseNoteAuthors = caseDetailsPage.getCaseNoteAuthors(); - Assert.assertFalse(caseNoteAuthors.contains(SYSTEM_USER_NAME)); - - NoteHistoryPage caseNoteHistoryPage = openCaseNoteHistory(caseId); - caseNoteAuthors = caseNoteHistoryPage.getNoteAuthors(); - Assert.assertFalse(caseNoteAuthors.contains(SYSTEM_USER_NAME)); - } - - @Test - public void testSystemNoteVisibilityInTaskForAdmin() { - updatePortalSetting(HIDE_SYSTEM_NOTES_FROM_HISTORY_ADMINISTRATOR.getKey(), "false"); - login(TestAccount.ADMIN_USER); - - TaskDetailsPage taskDetailsPage = openTaskDetails(); - List taskNoteAuthors = taskDetailsPage.getTaskNoteAuthors(); - Assert.assertTrue(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - String taskUuid = taskDetailsPage.getTaskUuid(); - taskDetailsPage.closeMainMenu(); - taskDetailsPage.refresh(); - taskDetailsPage.waitForNoteTableDisplayed(); - NoteHistoryPage taskNoteHistoryPage = openTaskNoteHistory(taskUuid); - taskNoteAuthors = taskNoteHistoryPage.getNoteAuthors(); - Assert.assertTrue(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - - updatePortalSetting(HIDE_SYSTEM_NOTES_FROM_HISTORY_ADMINISTRATOR.getKey(), "true"); - taskDetailsPage = openTaskDetails(); - taskNoteAuthors = taskDetailsPage.getTaskNoteAuthors(); - Assert.assertFalse(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - - taskUuid = taskDetailsPage.getTaskUuid(); - taskNoteHistoryPage = openTaskNoteHistory(taskUuid); - taskNoteAuthors = taskNoteHistoryPage.getNoteAuthors(); - Assert.assertFalse(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - } - - @Test - public void testSystemNoteVisibilityInTaskDetailForNormalUser() { - updatePortalSetting(HIDE_SYSTEM_NOTES_FROM_HISTORY.getKey(), "true"); - TaskDetailsPage taskDetailsPage = openTaskDetails(); - List taskNoteAuthors = taskDetailsPage.getTaskNoteAuthors(); - Assert.assertFalse(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - String taskUuid = taskDetailsPage.getTaskUuid(); - NoteHistoryPage taskNoteHistoryPage = openTaskNoteHistory(taskUuid); - taskNoteAuthors = taskNoteHistoryPage.getNoteAuthors(); - Assert.assertFalse(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - - updatePortalSetting(HIDE_SYSTEM_NOTES_FROM_HISTORY.getKey(), "false"); - taskDetailsPage = openTaskDetails(); - taskNoteHistoryPage.clickOnCheckboxShowSystemNotes(); - taskNoteHistoryPage.waitForNoteTableDisplayed(); - taskNoteAuthors = taskDetailsPage.getTaskNoteAuthors(); - Assert.assertTrue(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - taskUuid = taskDetailsPage.getTaskUuid(); - taskNoteHistoryPage = openTaskNoteHistory(taskUuid); - taskNoteAuthors = taskNoteHistoryPage.getNoteAuthors(); - Assert.assertTrue(taskNoteAuthors.contains(SYSTEM_USER_NAME)); - } - - private TaskDetailsPage openTaskDetails() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - TaskWidgetPage taskWidget = mainMenuPage.selectTaskMenu(); - return taskWidget.openTaskDetails(0); - } - - private CaseDetailsPage openCaseDetails() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - MainMenuPage mainMenuPage = newDashboardPage.openMainMenu(); - CaseWidgetPage casePage = mainMenuPage.selectCaseMenu(); - return casePage.openDetailsOfCaseHasName("Create note"); - } - - private NoteHistoryPage openCaseNoteHistory(String uuid) { - goToCaseNoteHistoryPage(uuid); - return new NoteHistoryPage(); - } - - private NoteHistoryPage openTaskNoteHistory(String uuid) { - goToTaskNoteHistoryPage(uuid); - return new NoteHistoryPage(); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemTaskHistoryVisibilityTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemTaskHistoryVisibilityTest.java deleted file mode 100644 index fc81d1ba093..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/SystemTaskHistoryVisibilityTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertFalse; -import static portal.guitest.common.Variable.HIDE_SYSTEM_TASKS_FROM_HISTORY; -import static portal.guitest.common.Variable.HIDE_SYSTEM_TASKS_FROM_HISTORY_ADMINISTRATOR; - -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.NoteHistoryPage; - -public class SystemTaskHistoryVisibilityTest extends BaseTest { - - @Override - public void setup() { - super.setup(); - redirectToRelativeLink(complexPaymentUrl); - } - - @Test - public void testSystemTaskVisibilityInCaseHistory() { - updatePortalSetting(HIDE_SYSTEM_TASKS_FROM_HISTORY.getKey(), "true"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - CaseDetailsPage caseDetailsPage = caseWidgetPage.openCaseDetailsFromActionMenuByCaseName("Create New Payment"); - String caseUuid = caseDetailsPage.getCaseUuid(); - goToCaseNoteHistoryPage(caseUuid); - NoteHistoryPage noteHistoryPage = new NoteHistoryPage(); - assertFalse(noteHistoryPage.getNoteAuthors().contains("System user")); - - updatePortalSetting(HIDE_SYSTEM_TASKS_FROM_HISTORY.getKey(), "false"); - WaitHelper.assertTrueWithRefreshPage(newDashboardPage, () -> { - goToCaseNoteHistoryPage(caseUuid); - return new NoteHistoryPage().getNoteAuthors().contains("System user"); - }); - } - - @Test - public void testSystemTaskVisibilityInCaseHistoryForAdmin() { - login(TestAccount.ADMIN_USER); - updatePortalSetting(HIDE_SYSTEM_TASKS_FROM_HISTORY_ADMINISTRATOR.getKey(), "false"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - CaseWidgetPage caseWidgetPage = newDashboardPage.openCaseList(); - CaseDetailsPage caseDetailsPage = caseWidgetPage.openCaseDetailsFromActionMenuByCaseName("Create New Payment"); - String caseUuid = caseDetailsPage.getCaseUuid(); - WaitHelper.assertTrueWithRefreshPage(newDashboardPage, () -> { - goToCaseNoteHistoryPage(caseUuid); - return new NoteHistoryPage().getNoteAuthors().contains("System user"); - }); - - updatePortalSetting(HIDE_SYSTEM_TASKS_FROM_HISTORY_ADMINISTRATOR.getKey(), "true"); - goToCaseNoteHistoryPage(caseUuid); - assertFalse(new NoteHistoryPage().getNoteAuthors().contains("System user")); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskActionTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskActionTest.java deleted file mode 100644 index f65a576c152..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskActionTest.java +++ /dev/null @@ -1,203 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.userexamples.page.LeaveRequestPage; - -public class TaskActionTest extends BaseTest { - - private TaskWidgetPage taskWidgetPage; - private TaskDetailsPage taskDetailsPage; - - static final String ACCESS_TASK_DETAILS = "ACCESS_TASK_DETAILS"; - - static final String DONE = "Done"; - static final String SUSPENDED = "Suspended"; - static final String IN_PROGRESS = "In progress"; - static final String READY_FOR_JOINING = "Ready for joining"; - static final String RESERVED = "Reserved"; - static final String DELAYED = "Delayed"; - static final String DESTROYED = "Destroyed"; - static final String FAILED = "Failed"; - static final String JOIN_FAILED = "Join failed"; - static final String WAITING_FOR_EVENT = "Waiting for event"; - - static final String DETAILS = "Details"; - static final String PROCESS_VIEWER = "Process Viewer"; - static final String CLEAR_EXPIRY = "Clear expiry"; - static final String DELEGATE = "Delegate"; - static final String RESERVE = "Reserve"; - static final String ADD_AD_HOC_TASK = "Add Ad-hoc Task"; - static final String RESET = "Reset"; - static final String DESTROY = "Destroy"; - static final String WORKFLOW_EVENTS = "Workflow Events"; - static final String TRIGGER_ESCALATION = "Trigger Escalation"; - static final String CLEAR_DELAY = "Clear delay"; - - @Override - @Before - public void setup() { - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), ACCESS_TASK_DETAILS); - createTestingTasks(); - } - - @SuppressWarnings("deprecation") - @Test - public void testVisibilityTaskActionForNormalUser() { - login(TestAccount.DEMO_USER); - redirectToRelativeLink(createTaskWithSystemState); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Ready for Join - assertTaskActionsByTaskState(READY_FOR_JOINING, Arrays.asList(DETAILS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Suspended - assertTaskActionsByTaskState(SUSPENDED, - Arrays.asList(DETAILS, DELEGATE, RESERVE, CLEAR_EXPIRY, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Reserved - taskWidgetPage.clickOnTaskActionLink(0); - taskWidgetPage.reserveTask(0); - taskWidgetPage.waitAjaxIndicatorDisappear(); - assertTaskActionsByTaskState(RESERVED, - Arrays.asList(DETAILS, DELEGATE, RESET, CLEAR_EXPIRY, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - - // In progress - TaskTemplatePage taskTemplatePage = taskDetailsPage.clickStartTask(); - taskTemplatePage.clickCancelLink(); - taskDetailsPage = new TaskDetailsPage(); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - assertTaskActionsByTaskState(IN_PROGRESS, - Arrays.asList(DETAILS, RESERVE, RESET, CLEAR_EXPIRY, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - } - - @SuppressWarnings("deprecation") - @Test - public void testVisibilityTaskActionForAdminUser() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTaskWithSystemState); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - // Ready for Join - assertTaskActionsByTaskState(READY_FOR_JOINING, - Arrays.asList(DETAILS, RESET, DESTROY, TRIGGER_ESCALATION, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Suspended - assertTaskActionsByTaskState(SUSPENDED, Arrays.asList(DETAILS, DELEGATE, RESERVE, CLEAR_EXPIRY, DESTROY, - WORKFLOW_EVENTS, TRIGGER_ESCALATION, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Reserved - taskWidgetPage.clickOnTaskActionLink(0); - taskWidgetPage.reserveTask(0); - taskWidgetPage.waitAjaxIndicatorDisappear(); - assertTaskActionsByTaskState(RESERVED, Arrays.asList(DETAILS, DELEGATE, RESET, CLEAR_EXPIRY, DESTROY, - WORKFLOW_EVENTS, TRIGGER_ESCALATION, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - - // In progress - TaskTemplatePage taskTemplatePage = taskDetailsPage.clickStartTask(); - taskTemplatePage.clickCancelLink(); - taskDetailsPage = new TaskDetailsPage(); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - assertTaskActionsByTaskState(IN_PROGRESS, Arrays.asList(DETAILS, RESERVE, RESET, CLEAR_EXPIRY, DESTROY, - WORKFLOW_EVENTS, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Done - assertTaskActionsByTaskState(DONE, Arrays.asList(DETAILS, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Delayed - assertTaskActionsByTaskState(DELAYED, - Arrays.asList(DETAILS, DELEGATE, CLEAR_DELAY, DESTROY, WORKFLOW_EVENTS, PROCESS_VIEWER, ADD_AD_HOC_TASK)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Destroyed - assertTaskActionsByTaskState(DESTROYED, Arrays.asList(DETAILS, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - } - - @Test - public void testVisibleTaskActionsWhenTaskStatusIsDoneAndDestroyed() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTaskWithSystemState); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - - taskWidgetPage.clickOnStartTaskLink(4); - LeaveRequestPage leaveRequestPage = new LeaveRequestPage(); - leaveRequestPage.fulfillAndSendMaternityLeaveRequest(); - - redirectToRelativeLink(createTaskWithSystemState); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - - // Done - List taskActionInTaskDetails = Arrays.asList(DETAILS, WORKFLOW_EVENTS, PROCESS_VIEWER); - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList(DONE)); - List actionInTaskList = taskWidgetPage.getActiveTaskAction(2); - assertTrue(actionInTaskList.size() == taskActionInTaskDetails.size()); - assertTrue(actionInTaskList.containsAll(taskActionInTaskDetails)); - - redirectToRelativeLink(createTaskWithSystemState); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - - // Destroyed - assertTaskActionsByTaskState(DESTROYED, Arrays.asList(DETAILS, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - } - - @Test - public void testVisibilityTaskActionForTechnicalStates() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTechnicalStateUrl); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - - // Failed - assertTaskActionsByTaskState(FAILED, Arrays.asList(DETAILS, RESET, DESTROY, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // Join failed - assertTaskActionsByTaskState(JOIN_FAILED, Arrays.asList(DETAILS, DESTROY, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - // waiting for event - assertTaskActionsByTaskState(WAITING_FOR_EVENT, Arrays.asList(DETAILS, DESTROY, WORKFLOW_EVENTS, PROCESS_VIEWER)); - taskWidgetPage = taskDetailsPage.goBackToTaskListFromTaskDetails(); - - } - - private void assertTaskActionsByTaskState(String state, List taskActionInTaskDetails) { - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList(state)); - List actionInTaskList = taskWidgetPage.getActiveTaskAction(0); - assertTrue(actionInTaskList.size() == taskActionInTaskDetails.size()); - assertTrue(actionInTaskList.containsAll(taskActionInTaskDetails)); - - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - if (taskActionInTaskDetails.isEmpty()) { - return; - } - assertTrue(taskDetailsPage.isActionLinkEnable()); - List actionInDetails = taskDetailsPage.getActiveTaskAction(); - var taskActionInTaskDetailsPage = new ArrayList<>(taskActionInTaskDetails); - taskActionInTaskDetailsPage.remove(DETAILS); - assertTrue(actionInDetails.size() == taskActionInTaskDetailsPage.size()); - assertTrue(actionInDetails.containsAll(taskActionInTaskDetailsPage)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskAnalysisWidgetTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskAnalysisWidgetTest.java deleted file mode 100644 index a90cf9dde00..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskAnalysisWidgetTest.java +++ /dev/null @@ -1,337 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.codec.binary.StringUtils; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.StatisticWidgetPage; -import portal.guitest.page.TaskAnalysisWidgetPage; - -public class TaskAnalysisWidgetTest extends BaseTest { - - private static final String ENABLE_CASE_OWNER_SETTING = Variable.ENABLE_CASE_OWNER.getKey(); - private NewDashboardPage newDashboardPage; - private StatisticWidgetPage statisticWidgetPage; - private MainMenuPage mainMenuPage; - - @Override - @Before - public void setup() { - super.setup(); - createTestingTasks(); - createTestData(); - login(TestAccount.ADMIN_USER); - grantPermissionOfPortal(); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - } - - private void grantPermissionOfPortal() { - String grantAllPermissionsForAdminUserURL = "portalKitTestHelper/14DE09882B540AD5/grantPortalPermission.ivp"; - redirectToRelativeLink(grantAllPermissionsForAdminUserURL); - } - - @Test - public void testNavigateToAnalysisPage() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - assertTrue(taskAnalysisWidgetPage.isDisplayed()); - } - - @Test - public void testBackToStatisticPage() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - statisticWidgetPage = taskAnalysisWidgetPage.navigateToStatisticPage(); - assertTrue(statisticWidgetPage.isDisplayed()); - } - - @Test - public void testAddColumns() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - - WebElement toggler = taskAnalysisWidgetPage.findColumnToggler(); - taskAnalysisWidgetPage.click(toggler); - - WebElement columnContainer = taskAnalysisWidgetPage.getDriver().findElement(By.tagName("body")) - .findElement(By.cssSelector(".ui-columntoggler")); - int numberOfCheckboxes = columnContainer.findElements(By.cssSelector(".ui-chkbox-box")).size(); - List unselectedColumnCheckboxes = - columnContainer.findElements(By.cssSelector(".ui-chkbox-box:not(.ui-state-active)")); - - unselectedColumnCheckboxes.forEach(elem -> taskAnalysisWidgetPage.click(elem)); - taskAnalysisWidgetPage.waitForPageLoaded(); - - int numberOfColumns = taskAnalysisWidgetPage.findElementById("task-widget:statistic-result-form:task-table_head") - .findElements(By.cssSelector("th[scope='col']:not(.ui-helper-hidden)")).size(); - assertEquals(numberOfColumns, numberOfCheckboxes); - } - - @Test - public void testRemoveColumns() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - - WebElement toggler = taskAnalysisWidgetPage.findColumnToggler(); - taskAnalysisWidgetPage.click(toggler); - - WebElement columnContainer = taskAnalysisWidgetPage.getDriver().findElement(By.tagName("body")) - .findElement(By.cssSelector(".ui-columntoggler")); - List selectedColumnCheckboxes = - columnContainer.findElements(By.cssSelector(".ui-chkbox-box.ui-state-active")); - - taskAnalysisWidgetPage.click(selectedColumnCheckboxes.get(0)); - taskAnalysisWidgetPage.click(selectedColumnCheckboxes.get(1)); - selectedColumnCheckboxes.remove(0); - selectedColumnCheckboxes.remove(1); - - taskAnalysisWidgetPage.waitForPageLoaded(); - - int numberOfColumns = taskAnalysisWidgetPage.findElementById("task-widget:statistic-result-form:task-table_head") - .findElements(By.cssSelector("th[scope='col']:not(.ui-helper-hidden)")).size(); - - assertEquals(numberOfColumns, selectedColumnCheckboxes.size()); - } - - @Test - public void testApplyTaskFilters() { - String nameKeyword = "request"; - String prioritySeletion = "NORMAL"; - - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.openAdvancedTaskFilter("Name", "name"); - taskAnalysisWidgetPage.filterByTaskName(nameKeyword); - - taskAnalysisWidgetPage.openAdvancedTaskFilter("Priority", "priority"); - List selectedPriorities = new ArrayList<>(); - selectedPriorities.add(prioritySeletion); - taskAnalysisWidgetPage.filterByTaskPriority(selectedPriorities); - taskAnalysisWidgetPage.clickApplyFilter(); - - List results = taskAnalysisWidgetPage.getRowsInTaskTable(); - - assertEquals(2, results.size()); - - for (WebElement resultRow : results) { - List resultCells = resultRow.findElements(By.cssSelector("td:not([class='ui-helper-hidden'])")); - assertTrue(resultCells.get(2).getText().toLowerCase().contains(nameKeyword)); - assertTrue(resultCells.get(3).getText().equals(prioritySeletion)); - } - } - - @Test - public void testApplyCaseFilters() { - String keyword = "request"; - String stateSeletion = "In progress"; - - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.openAdvancedCaseFilter("State", "state"); - taskAnalysisWidgetPage.openAdvancedCaseFilter("Name", "case-name"); - taskAnalysisWidgetPage.filterByCaseName(keyword); - - List selectedStates = new ArrayList<>(); - selectedStates.add(stateSeletion); - taskAnalysisWidgetPage.filterByCaseState(selectedStates); - taskAnalysisWidgetPage.clickApplyFilter(); - - List results = taskAnalysisWidgetPage.getRowsInTaskTable(); - - assertEquals(4, results.size()); - - for (WebElement resultRow : results) { - List resultCells = resultRow.findElements(By.cssSelector("td:not([class='ui-helper-hidden'])")); - assertTrue(resultCells.get(0).getText().toLowerCase().contains(keyword)); - assertTrue(resultCells.get(1).getText().equals("RUNNING")); - } - } - - @Test - public void testApplyTaskCategoryFilter() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.openAdvancedTaskFilter("Category", "task-category"); - taskAnalysisWidgetPage.filterByTaskCategory("Other Leave"); - taskAnalysisWidgetPage.clickApplyFilter(); - List results = taskAnalysisWidgetPage.getRowsInTaskTable(); - - assertEquals(2, results.size()); - } - - @Test - public void testApplyCaseCategoryFilter() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.openAdvancedCaseFilter("Case category", "case-category"); - taskAnalysisWidgetPage.filterByCaseCategory("Leave Request"); - taskAnalysisWidgetPage.clickApplyFilter(); - - List results = taskAnalysisWidgetPage.getRowsInTaskTable(); - assertEquals(4, results.size()); - } - - @Test - public void testApplyCaseOwnerFilter() { - updatePortalSetting(ENABLE_CASE_OWNER_SETTING, "true"); - redirectToRelativeLink(userIsOwnerUrl); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.filterByOwner("Demo"); - taskAnalysisWidgetPage.clickApplyFilter(); - - List results = taskAnalysisWidgetPage.getRowsInTaskTable(); - assertEquals(2, results.size()); - updatePortalSetting(ENABLE_CASE_OWNER_SETTING, "false"); - } - - @SuppressWarnings("deprecation") - @Test - public void testAddCaseOwnerColumn() { - updatePortalSetting(ENABLE_CASE_OWNER_SETTING, "true"); - newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - - WebElement toggler = taskAnalysisWidgetPage.findColumnToggler(); - taskAnalysisWidgetPage.click(toggler); - taskAnalysisWidgetPage.waitAjaxIndicatorDisappear(); - - WebElement columnContainer = taskAnalysisWidgetPage.getDriver().findElement(By.tagName("body")) - .findElement(By.cssSelector(".ui-columntoggler")); - List checkboxes = columnContainer.findElements(By.cssSelector("li.ui-columntoggler-item")); - - checkboxes.forEach(elem -> { - if (StringUtils.equals(elem.getText(), "Case Owner")) { - elem.findElement(By.className("ui-chkbox")).click(); - } - }); - taskAnalysisWidgetPage.isElementDisplayed(By.id("task-widget:statistic-result-form:task-table:case-owner")); - updatePortalSetting(ENABLE_CASE_OWNER_SETTING, "false"); - } - - @Test - public void testSavePublicFilterSet() { - String filterSetName = "Filters for annual"; - - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - addFilters(taskAnalysisWidgetPage); - taskAnalysisWidgetPage.saveFilterSet(filterSetName, false); - - statisticWidgetPage = taskAnalysisWidgetPage.navigateToStatisticPage(); - final TaskAnalysisWidgetPage secondTaskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - secondTaskAnalysisWidgetPage.loadFilterSet(filterSetName, false); - secondTaskAnalysisWidgetPage.waitForTaskDataChangeToSpecificSize(1); - List resultCells = secondTaskAnalysisWidgetPage.getRowsInTaskTable().get(0).findElements(By.cssSelector("td:not([class='ui-helper-hidden'])")); - assertTrue(resultCells.get(0).getText().toLowerCase().contains("request")); - assertTrue(resultCells.get(1).getText().equals("RUNNING")); - assertTrue(resultCells.get(2).getText().toLowerCase().contains("annual")); - } - - @Test - public void testSavePrivateFilterSet() { - String filterSetName = "Filters for annual"; - - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - addFilters(taskAnalysisWidgetPage); - taskAnalysisWidgetPage.saveFilterSet(filterSetName, true); - - statisticWidgetPage = taskAnalysisWidgetPage.navigateToStatisticPage(); - TaskAnalysisWidgetPage secondTaskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - secondTaskAnalysisWidgetPage.loadFilterSet(filterSetName, true); - secondTaskAnalysisWidgetPage.waitForTaskDataChangeToSpecificSize(1); - - List resultCells = secondTaskAnalysisWidgetPage.getRowsInTaskTable().get(0).findElements(By.cssSelector("td:not([class='ui-helper-hidden'])")); - assertTrue(resultCells.get(0).getText().toLowerCase().contains("request")); - assertTrue(resultCells.get(1).getText().equals("RUNNING")); - assertTrue(resultCells.get(2).getText().toLowerCase().contains("annual")); - } - - private void createTestData() { - redirectToRelativeLink(create12CasesWithCategoryUrl); - } - - private void addFilters(TaskAnalysisWidgetPage taskAnalysisWidgetPage) { - String taskNameKeyword = "annual"; - String taskCategory = "Annual Leave"; - String caseNameKeyword = "request"; - String caseCategory = "Leave Request"; - String caseState = "In progress"; - - taskAnalysisWidgetPage.openAdvancedCaseFilter("State", "state"); - taskAnalysisWidgetPage.openAdvancedTaskFilter("Name", "name"); - taskAnalysisWidgetPage.filterByTaskName(taskNameKeyword); - - taskAnalysisWidgetPage.openAdvancedTaskFilter("Category", "task-category"); - taskAnalysisWidgetPage.filterByTaskCategory(taskCategory); - - taskAnalysisWidgetPage.openAdvancedCaseFilter("Name", "case-name"); - taskAnalysisWidgetPage.filterByCaseName(caseNameKeyword); - - taskAnalysisWidgetPage.openAdvancedCaseFilter("Case category", "case-category"); - taskAnalysisWidgetPage.filterByCaseCategory(caseCategory); - - List selectedStates = new ArrayList<>(); - selectedStates.add(caseState); - taskAnalysisWidgetPage.filterByCaseState(selectedStates); - } - - @Test - public void testDefaultAndResetFilter() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - assertTrue(taskAnalysisWidgetPage.getFilterName().contains("Default filter")); - - taskAnalysisWidgetPage.openAdvancedTaskFilter("Name", "name"); - taskAnalysisWidgetPage.filterByTaskName("request"); - assertTrue(taskAnalysisWidgetPage.isResetButtonShown()); - - taskAnalysisWidgetPage.resetFilter(); - assertTrue(taskAnalysisWidgetPage.getFilterName().contains("Default filter")); - } - - @Test - public void testRemoveAndReloadFilter() { - // Task Responsible, Case Creator - String filterSetName = "saveUserFilter"; - - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.filterByResponsible("Demo","Responsible","responsible"); - taskAnalysisWidgetPage.filterUserInCase("Demo","Creator","creator"); - - taskAnalysisWidgetPage.saveFilterSet(filterSetName, false); - MainMenuPage mainMenuPage = new MainMenuPage(); - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.loadFilterSet(filterSetName, false); - - taskAnalysisWidgetPage.removeResponsible(); - taskAnalysisWidgetPage.removeUserInFilter(); - - statisticWidgetPage = mainMenuPage.selectStatisticDashboard(); - statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.loadFilterSet(filterSetName, false); - - assertTrue(taskAnalysisWidgetPage.getUser("responsible").contains("Demo")); - assertTrue(taskAnalysisWidgetPage.getUser("creator").contains("Demo")); - } - - @Test - public void testTaskFilterForUnavailableActivator() { - TaskAnalysisWidgetPage taskAnalysisWidgetPage = statisticWidgetPage.navigateToTaskAnalysisPage(); - taskAnalysisWidgetPage.openNoActivatorFilter("Missing activator"); - taskAnalysisWidgetPage.filterByUnavailableActivator(); - taskAnalysisWidgetPage.clickApplyFilter(); - List results = taskAnalysisWidgetPage.getRowsInTaskTable(); - assertEquals(2, results.size()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskCategoryMenuTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskCategoryMenuTest.java deleted file mode 100644 index 704d143415a..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskCategoryMenuTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.TaskWidgetPage; - -public class TaskCategoryMenuTest extends BaseTest { - - @Before - @Override - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - } - - @Test - public void testSelectTaskCategoryMenuAsNormalUser() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(3, taskWidgetPage.countTasks()); - } - - @Test - public void testSelectTaskCategoryMenuAsAdminRole() { - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(4, taskWidgetPage.countTasks()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDescriptionChangeTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDescriptionChangeTest.java deleted file mode 100644 index a924211b954..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDescriptionChangeTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserProfilePage; - -public class TaskDescriptionChangeTest extends BaseTest { - - private TaskWidgetPage taskWidgetPage; - - @Override - @Before - public void setup() { - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestingTasks(); - } - - @Test - public void testChangeTaskDescription() { - login(TestAccount.ADMIN_USER); - int firstTask = 0; - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(firstTask); - testChangeTaskDescription("Hello World!", "Hello World!", taskWidgetPage); - testChangeTaskDescription( - "HTML description could contain malicious script but it will be sanitized.", - "HTML description could contain malicious script but it will be sanitized.", taskWidgetPage); - testChangeTaskDescription("", "No description", taskWidgetPage); - testChangeTaskDescription("And you can change description if it is empty", - "And you can change description if it is empty", taskWidgetPage); - } - - private void testChangeTaskDescription(String newDescription, String shownDescriptionInDetails, TaskWidgetPage taskWidgetPage) { - taskWidgetPage.changeDescriptionOfTask(newDescription); - assertEquals(taskWidgetPage.getTaskDescription(), shownDescriptionInDetails); - } - - @Test - public void testUserWithoutPermissionCannotChangeTaskName() { - int firstTask = 0; - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(firstTask); - assertFalse(taskWidgetPage.isTaskNameChangeComponentPresented(firstTask)); - } - - @Ignore - @Test - /** - * This test is ignored because it need specific configuration on engine to run correctly - */ - public void testChangeTaskDescriptionInMultiLanguage() { - login(TestAccount.ADMIN_USER); - int firstTask = 0; - var taskNameEn = "Maternity Leave Request"; - var taskNameGer = "Antrag auf Mutterschaftsurlaub"; - var taskDescriptionEn = "Hello World! - English"; - var taskDescriptionGer = "Hello World! - German"; - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy(taskNameEn); - taskWidgetPage.openTaskDetails(firstTask); - testChangeTaskDescription(taskDescriptionEn, taskDescriptionEn, taskWidgetPage); - - // Change language to German then change description - changeLanguage(3); - taskWidgetPage.filterTasksInExpandedModeBy(taskNameGer); - taskWidgetPage.openTaskDetails(firstTask); - testChangeTaskDescription(taskDescriptionGer, taskDescriptionGer, taskWidgetPage); - - // Change to English then verify description - changeLanguage(1); - taskWidgetPage.filterTasksInExpandedModeBy(taskNameEn); - taskWidgetPage.openTaskDetails(firstTask); - assertEquals(taskWidgetPage.getTaskDescription(), taskDescriptionEn); - - // Change to German then verify description - changeLanguage(3); - taskWidgetPage.filterTasksInExpandedModeBy(taskNameGer); - taskWidgetPage.openTaskDetails(firstTask); - assertEquals(taskWidgetPage.getTaskDescription(), taskDescriptionGer); - } - - public void changeLanguage(int index) { - UserProfilePage userProfilePage = taskWidgetPage.openMyProfilePage(); - userProfilePage.selectLanguage(index); - userProfilePage.save(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - } - - @After - public void resetlanguage() { - resetLanguageOfCurrentUser(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDetailsTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDetailsTest.java deleted file mode 100644 index aece3c37020..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskDetailsTest.java +++ /dev/null @@ -1,243 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; - -import org.apache.commons.lang.StringUtils; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.DateTimePattern; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.TestRole; -import portal.guitest.common.Variable; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserProfilePage; - -public class TaskDetailsTest extends BaseTest { - - private static final String COMMENT_CONTENT = "Test comment"; - private TaskWidgetPage taskWidgetPage; - private TaskDetailsPage taskDetailsPage; - - @Override - @Before - public void setup() { - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestingTasks(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - new NewDashboardPage(); - } - - @Test - public void testDelegateTaskInTaskDetail() { - login(TestAccount.ADMIN_USER); - taskDetailsPage = openDetailsPageOfFirstTask(); - assertTrue(StringUtils.equalsIgnoreCase(TestRole.EVERYBODY_ROLE, taskDetailsPage.getTaskResponsible())); - taskDetailsPage.openTaskDelegateDialog(); - taskDetailsPage.selectDelegateResponsible(TestAccount.HR_ROLE_USER.getFullName(), false); - assertTrue(StringUtils.equalsIgnoreCase(TestAccount.HR_ROLE_USER.getFullName(), taskDetailsPage.getTaskResponsible())); - - taskDetailsPage.openTaskDelegateDialog(); - taskDetailsPage.addCommentOnTaskDelegationDialog(COMMENT_CONTENT); - taskDetailsPage.selectDelegateResponsible(TestRole.HR_ROLE, true); - assertTrue(StringUtils.equalsIgnoreCase(TestRole.HR_ROLE, taskDetailsPage.getTaskResponsible())); - assertTrue(StringUtils.contains(taskDetailsPage.getFirstTaskNoteComment(), COMMENT_CONTENT)); - } - - private TaskDetailsPage openDetailsPageOfFirstTask() { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - return taskWidgetPage.openTaskDetails(0); - } - - @Test - public void testChangeTaskDeadline() { - setFormattingLanguage(); - LocalDateTime now = LocalDateTime.now(); - String tomorrowStringLiteral = prepareTomorrowAsString(now); - taskDetailsPage = openDetailsPageOfFirstTask(); - taskDetailsPage.changeExpiryOfTaskAt(tomorrowStringLiteral); - assertEquals(prepareTomorrowAsLocaleDateString(now), taskDetailsPage.getExpiryOfTaskAt()); - } - - private void setFormattingLanguage() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - userProfilePage.inputFormattingLanguage("English (United Kingdom)"); - newDashboardPage = userProfilePage.save(); - } - - @Test - public void testChangeTaskDeadlineWithAfterEscalationIsNA() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTestingCaseMapUrl); - setFormattingLanguage(); - LocalDateTime now = LocalDateTime.now(); - String tomorrowStringLiteral = prepareTomorrowAsString(now); - taskDetailsPage = openDetailsPageOfFirstTask(); - taskDetailsPage.changeExpiryOfTaskAt(tomorrowStringLiteral); - assertTrue(StringUtils.equalsIgnoreCase(prepareTomorrowAsLocaleDateString(now), taskDetailsPage.getExpiryOfTaskAt())); - String firstTaskNoteComment = taskDetailsPage.getFirstTaskNoteComment(); - assertTrue(StringUtils.contains(firstTaskNoteComment, "Portal Admin User (admin) has set deadline to task")); - } - - @Test - public void testRemoveTaskDeadline() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTestingTasksUrl); - taskDetailsPage = openDetailsPageOfFirstTask(); - taskDetailsPage.openActionPanel(); - assertTrue(taskDetailsPage.isClearDeadlineDisplayed()); - taskDetailsPage.clickOnClearDeadlineTime(); - assertTrue(StringUtils.equalsIgnoreCase("N/A", taskDetailsPage.getExpiryOfTaskAt())); - assertTrue(StringUtils.contains(taskDetailsPage.getFirstTaskNoteComment(), "Portal Admin User (admin) has removed expiry time of task")); - } - - @Test - public void testChangeTaskEscaltionActivator() { - login(TestAccount.ADMIN_USER); - taskDetailsPage = openDetailsPageOfFirstTask(); - taskDetailsPage.changeEscaltionActivatorTo("HR", false); - assertTrue(StringUtils.equalsIgnoreCase("Human resources department", taskDetailsPage.getAfterEscalation())); - assertTrue(StringUtils.contains(taskDetailsPage.getFirstTaskNoteComment(), "changed from Everybody to Human resources department")); - } - - @Test - public void testCannotChangeTaskEscaltionActivator() { - login(TestAccount.DEMO_USER); - taskDetailsPage = openDetailsPageOfFirstTask(); - assertFalse(taskDetailsPage.canChangeEscalationActivator()); - } - - private String prepareTomorrowAsString(LocalDateTime now) { - LocalDateTime tomorrow = now.plusDays(1); - return tomorrow.format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - } - - private String prepareTomorrowAsLocaleDateString(LocalDateTime now) { - LocalDateTime tommorrow = now.plusDays(1); - return tommorrow.format(DateTimeFormatter.ofPattern(DateTimePattern.LOCALE_DATE_TIME_PATTERN, Locale.UK)); - } - - @Test - public void testClearTheDelayTimestampOfTask() { - openDelayTask(); - assertTrue(StringUtils.equalsIgnoreCase("DELAYED", taskDetailsPage.getTaskState())); - taskDetailsPage.openActionPanel(); - assertTrue(taskDetailsPage.isClearDelayTimeDisplayed()); - taskDetailsPage.clickOnClearDelayTime(); - assertTrue(StringUtils.equalsIgnoreCase("OPEN", taskDetailsPage.getTaskState())); - assertTrue(StringUtils.equalsIgnoreCase("N/A", taskDetailsPage.getTaskDelayTime())); - } - - @Test - public void testChangeDelayTimestamp() { - setFormattingLanguage(); - openDelayTask(); - assertTrue(StringUtils.equalsIgnoreCase("DELAYED", taskDetailsPage.getTaskState())); - LocalDateTime now = LocalDateTime.now(); - String tomorrow = prepareTomorrowAsString(now); - String tomorrowWithLocale = prepareTomorrowAsLocaleDateString(now); - taskDetailsPage.updateDelayTimestamp(tomorrow,tomorrowWithLocale); - assertTrue(StringUtils.equalsIgnoreCase("DELAYED", taskDetailsPage.getTaskState())); - refreshPage(); - taskDetailsPage = new TaskDetailsPage(); - String yesterday = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - String yesterdayWithLocale = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern(DateTimePattern.LOCALE_DATE_TIME_PATTERN, Locale.UK)); - taskDetailsPage.updateDelayTimestamp(yesterday,yesterdayWithLocale); - assertTrue(StringUtils.equalsIgnoreCase("OPEN", taskDetailsPage.getTaskState())); - } - - @Test - public void testShowTaskWorkflowEvent() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTechnicalStateUrl); - taskDetailsPage = openDetailsPageOfFirstTask(); - String eventData = taskDetailsPage.openWorkflowEventDialog(); - assertTrue(eventData.contains("admin")); - } - - private void openDelayTask() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTaskWithSystemState); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList("Delayed")); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - } - - @Test - public void testShowDurationOfDoneTask() { - login(TestAccount.ADMIN_USER); - openFirstTaskInCompletedTasks(); - assertFalse(StringUtils.equalsIgnoreCase("", taskDetailsPage.getDurationTimeText())); - } - - private void openFirstTaskInCompletedTasks() { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openAdvancedFilter("Completed on (from/to)", "completed"); - filterByDateType("completed"); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - } - - private void filterByDateType(String dateType) { - DateFormat dateFormat = new SimpleDateFormat(DateTimePattern.DATE_TIME_PATTERN); - Calendar calendar = Calendar.getInstance(); - Date today = new Date(); - calendar.setTime(today); - - calendar.add(Calendar.DAY_OF_YEAR, -1); - Date yesterday = calendar.getTime(); - String yesterdayText = dateFormat.format(yesterday); - - calendar.add(Calendar.DAY_OF_YEAR, 2); - Date tomorrow = calendar.getTime(); - String tomorrowText = dateFormat.format(tomorrow); - - taskWidgetPage.filterByDate(dateType, yesterdayText, tomorrowText); - } - - @Test - public void testShowNotAvailableValues() { - login(TestAccount.ADMIN_USER); - openFirstTaskInTaskList(); - assertTrue(StringUtils.equalsIgnoreCase(taskDetailsPage.getTaskDelayTime(), "N/A")); - - login(TestAccount.GUEST_USER); - openFirstTaskInTaskList(); - assertFalse(taskDetailsPage.isDelayTimeDisplayed()); - } - - private void openFirstTaskInTaskList() { - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - } - - @Test - public void testDragDropWidgets() { - openFirstTaskInTaskList(); - taskDetailsPage.clickOnSwitchToEditModeButton(); - taskDetailsPage.waitForSwitchToViewModeButtonDisplayed(); - taskDetailsPage.drapAndDropWidgets("note", "document"); - taskDetailsPage.drapAndDropWidgets("document", "note"); - taskDetailsPage.drapAndDropWidgets("note", "document"); - taskDetailsPage.drapAndDropWidgets("document", "note"); - taskDetailsPage.clickOnSwitchToViewModeButton(); - taskDetailsPage.clickOnSwitchToEditModeButton(); - taskDetailsPage.waitForResetButtonDisplayed(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskFilterTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskFilterTest.java deleted file mode 100644 index aab4d426fe9..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskFilterTest.java +++ /dev/null @@ -1,285 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; - -public class TaskFilterTest extends BaseTest { - - @Before - @Override - public void setup() { - super.setup(); - redirectToRelativeLink(createTestingTasksUrl); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - } - - @Test - public void testFilterTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(3, taskWidgetPage.countTasks()); - taskWidgetPage.filterTasksInExpandedModeBy("Maternity"); - assertEquals(1, taskWidgetPage.countTasks()); - taskWidgetPage.filterTasksInExpandedModeBy("Sick Leave Request Description"); - assertEquals(1, taskWidgetPage.countTasks()); - } - - @Test - public void testAdvancedFilterTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(3, taskWidgetPage.countTasks()); - - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription("Maternity"); - - assertEquals(1, taskWidgetPage.countTasks()); - } - - @Test - public void testShowDoneStateFilterForNormalUser() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(3, taskWidgetPage.countTasks()); - - String stateFilterValue = taskWidgetPage.getFilterValue("state-filter"); - assertEquals("State: Created, Suspended, In progress, Reserved, Ready for joining", stateFilterValue); - - taskWidgetPage.openStateFilter(); - assertTrue(taskWidgetPage.getListStateFilterSelection().contains("Done")); - } - - @Test - public void testKeepSessionFilter() { - MainMenuPage mainMenuPage = new MainMenuPage(); - final TaskWidgetPage taskWidgetPage = mainMenuPage.openTaskList(); - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription("Maternity"); - - mainMenuPage.openCaseList(); - TaskWidgetPage taskWidgetPage2 = mainMenuPage.openTaskList(); - assertEquals(1, taskWidgetPage2.countTasks()); - assertEquals(true, taskWidgetPage2.isAdvancedFilterDisplayed("description")); - } - - @Test - public void testSaveTaskFilter() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - - String filterName = "Maternity"; - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription(filterName); - taskWidgetPage.saveFilter(filterName); - assertEquals(filterName, taskWidgetPage.getFilterName()); - } - - @SuppressWarnings("deprecation") - @Test - public void testSaveTaskFilterForAdmin() { - List normalStates = Arrays.asList("Suspended", "In progress"); - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - - MainMenuPage mainMenuPage = new MainMenuPage(); - TaskWidgetPage taskWidgetPage = mainMenuPage.openTaskList(); - - String filterName = "For admins"; - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription("Maternity"); - - WebElement saveFilterDialog = taskWidgetPage.openSaveFilterDialog(); - assertEquals("All administrators", saveFilterDialog - .findElement(By.cssSelector("label[for='task-widget:filter-save-form:save-filter-type-radio:1']")).getText()); - taskWidgetPage.click(saveFilterDialog.findElement(By.cssSelector("a"))); - taskWidgetPage.waitAjaxIndicatorDisappear(); - taskWidgetPage.saveAdminFilter(filterName); - - taskWidgetPage.filterByStates(normalStates); - - saveFilterDialog = taskWidgetPage.openSaveFilterDialog(); - assertEquals("All users", saveFilterDialog - .findElement(By.cssSelector("label[for='task-widget:filter-save-form:save-filter-type-radio:1']")).getText()); - taskWidgetPage.click(saveFilterDialog.findElement(By.cssSelector("a"))); - taskWidgetPage.waitAjaxIndicatorDisappear(); - - login(TestAccount.DEMO_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - taskWidgetPage = mainMenuPage.openTaskList(); - assertFalse(taskWidgetPage.isExistedFilter(filterName)); - } - - @Test - public void testShowTaskWithNotExistsedActivatorToPersonHaveTaskReadAllPermission() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(createTaskWithNotExistedActivatorUrl); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(6, taskWidgetPage.countTasks()); - - taskWidgetPage.clickOnTaskStatesAndApply(Arrays.asList("Suspended")); - assertEquals(4, taskWidgetPage.countTasks()); - assertEquals("Not exist user", taskWidgetPage.getResponsibleOfTaskAt(0)); - } - - @Test - public void testShowSystemStatesFilterForAdminUser() { - List adminStates = Arrays.asList("Created", "Ready for joining", "Suspended", "In progress", "Reserved", - "Delayed", "Done", "Destroyed", "Failed", "Join failed", "Waiting for event"); - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - MainMenuPage mainMenuPage = new MainMenuPage(); - TaskWidgetPage taskWidgetPage = mainMenuPage.openTaskList(); - - String stateFilterValue = taskWidgetPage.getFilterValue("state-filter"); - assertEquals("State: All", stateFilterValue); - - taskWidgetPage.openStateFilter(); - List states = taskWidgetPage.getListStateFilterSelection(); - assertTrue(states.size() == adminStates.size()); - assertTrue(states.containsAll(adminStates)); - } - - @Test - public void testNotShowTaskWithNotExistsedActivatorToPersonNotHaveTaskReadAllPermission() { - redirectToRelativeLink(createTaskWithNotExistedActivatorUrl); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - - assertEquals(3, taskWidgetPage.countTasks()); - } - - @Test - public void testCategory() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - String taskCategoryId = "task-category"; - taskWidgetPage.openAdvancedFilter("Category", taskCategoryId); - assertEquals("Category: All", taskWidgetPage.getFilterValue(taskCategoryId + "-filter")); - taskWidgetPage.openCategoryFilter(); - assertTrue(taskWidgetPage.isAllCategoriesSelected()); - - taskWidgetPage.toggleNoCategory(); - - assertTrue(taskWidgetPage.isAllCategoriesUnselected()); - - taskWidgetPage.applyCategoryFilter(); - - assertNotEquals("Category: All", taskWidgetPage.getFilterValue(taskCategoryId + "-filter")); - } - - @Test - public void testRemoveResponsibleAndSwitchFilter() { - // Prepare 2 filter - String filterResponsible = "Responsible"; - String filterMaternity = "Maternity"; - - MainMenuPage mainMenuPage = new MainMenuPage(); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription(filterMaternity); - taskWidgetPage.saveFilter(filterMaternity); - - taskWidgetPage = mainMenuPage.openTaskList(); - taskWidgetPage.filterByResponsible("Everybody"); - taskWidgetPage.saveFilter(filterResponsible); - // Switch filter and remove responsible - taskWidgetPage.openSavedFilters(filterMaternity); - taskWidgetPage.openSavedFilters(filterResponsible); - taskWidgetPage.removeResponsibleFilter(); - taskWidgetPage.openSavedFilters(filterMaternity); - taskWidgetPage.openSavedFilters(filterResponsible); - - assertTrue(taskWidgetPage.getResponsible().contains("Everybody")); - } - - @Test - public void testResponsibleWithChangeFilter() { - // Prepare 2 filter - String filterResponsible = "Responsible"; - String filterMaternity = "Maternity"; - - MainMenuPage mainMenuPage = new MainMenuPage(); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByResponsible("Everybody"); - taskWidgetPage.filterByDescription(filterMaternity); - taskWidgetPage.saveFilter(filterMaternity); - - taskWidgetPage = mainMenuPage.openTaskList(); - taskWidgetPage.filterByResponsible("Demo"); - taskWidgetPage.saveFilter(filterResponsible); - // Change filter and verify responsible changed - taskWidgetPage.openSavedFilters(filterMaternity); - - assertTrue(taskWidgetPage.getResponsible().contains("Everybody")); - } - - @Test - public void testDefaultFilter() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidgetPage.getFilterName().contains("Default filter")); - } - - @Test - public void testNoSelectionWhenChangeFilter() { - String filterMaternity = "Maternity"; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription(filterMaternity); - taskWidgetPage.saveFilter(filterMaternity); - taskWidgetPage.filterByResponsible("Demo"); - - assertTrue(taskWidgetPage.getFilterName().contains("No Selection")); - } - - @Test - public void testResetFilter() { - String filterMaternity = "Maternity"; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openAdvancedFilter("Description", "description"); - taskWidgetPage.filterByDescription(filterMaternity); - taskWidgetPage.resetFilter(); - - assertTrue(taskWidgetPage.getFilterName().contains("Default filter")); - } - - @Test - public void testTaskFilterForUnavailableActivator() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - - MainMenuPage mainMenuPage = new MainMenuPage(); - TaskWidgetPage taskWidgetPage = mainMenuPage.openTaskList(); - - String filterName = "For admins"; - taskWidgetPage.openNoActivatorFilter("Missing activator"); - assertEquals(4, taskWidgetPage.countTasks()); - taskWidgetPage.filterByUnavailableActivator(true); - assertEquals(1, taskWidgetPage.countTasks()); - - WebElement saveFilterDialog = taskWidgetPage.openSaveFilterDialog(); - assertEquals("All administrators", saveFilterDialog - .findElement(By.cssSelector("label[for='task-widget:filter-save-form:save-filter-type-radio:1']")).getText()); - taskWidgetPage.saveAdminFilter("admin filter"); - - login(TestAccount.DEMO_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - mainMenuPage = newDashboardPage.openMainMenu(); - taskWidgetPage = mainMenuPage.openTaskList(); - assertFalse(taskWidgetPage.isExistedFilter(filterName)); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskPriorityChangeTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskPriorityChangeTest.java deleted file mode 100644 index 78524c99724..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskPriorityChangeTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; - -public class TaskPriorityChangeTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestingTasks(); - } - - @Test - public void testChangeTaskPriority() { - login(TestAccount.ADMIN_USER); - int firstTask = 0; - int priorityIntValue = 2; - String priorityStringValue = "NORMAL"; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskDetailsPage taskDetailsPage = taskWidgetPage.openTaskDetails(firstTask); - taskDetailsPage.changePriorityOfTask(priorityIntValue); - assertTrue(priorityStringValue.equals(taskDetailsPage.getPriorityOfTask())); - } - - @Test - public void testUserWithoutPermissionCannotChangeTaskPriority() { - int firstTask = 0; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(firstTask); - assertFalse(taskWidgetPage.isTaskPriorityChangeComponentPresented(firstTask)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateIFrameTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateIFrameTest.java deleted file mode 100644 index d10c4528b20..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateIFrameTest.java +++ /dev/null @@ -1,120 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.Variable; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class TaskTemplateIFrameTest extends BaseTest { - - private static final String CUSTOM_PARAMS_TEMPLATE_TASK_URL = "portal-developer-examples/1718293B3F6E5478/start.ivp"; - private static final String IFRAME_TASK_URL = - "portal-developer-examples/16E5DB746865BCEC/CreateInvestment.ivp?embedInFrame"; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - } - - @Test - public void testCustomParamsForIFrameTaskTemplate() { - redirectToRelativeLink(CUSTOM_PARAMS_TEMPLATE_TASK_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("IFrame task with custom params"); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTaskWithouWaitForTaskActionPresent(0); - assertFalse(taskTemplatePage.isTaskNameDisplayed()); - assertFalse(taskTemplatePage.isTaskActionDisplayed()); - assertFalse(taskTemplatePage.isCaseInfoButtonDisplayed()); - } - - @Test - public void testDisplayWarningInIFrameTaskTemplate() { - redirectToRelativeLink(IFRAME_TASK_URL); - waitForTemplateRender(); - final TaskTemplatePage taskTemplatePage = new TaskTemplatePage(); - taskTemplatePage.clickOnLogo(); - By leaveButton = By.id("task-leave-warning-component:leave-button"); - WaitHelper.assertTrueWithWait(() -> taskTemplatePage.isElementDisplayed(leaveButton)); - } - - @Test - public void testNotDisplayWarningInIFrameTaskTemplate() { - redirectToRelativeLink(IFRAME_TASK_URL); - waitForTemplateRender(); - TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskTemplatePage taskTemplatePage2 = taskWidgetPage.startTask(0); - taskTemplatePage2.clickOnLogo(); - new NewDashboardPage(); - } - - @Test - public void testRedirectToApplicationHome() { - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - redirectToRelativeLink(IFRAME_TASK_URL); - waitForTemplateRender(); - TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskTemplatePage taskTemplatePage2 = taskWidgetPage.startTask(0); - taskTemplatePage2.backToHomeInIFrameApprovalTask(); - new NewDashboardPage(); - } - - @Test - public void testStickyTaskList() { - redirectToRelativeLink(IFRAME_TASK_URL); - waitForTemplateRender(); - TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage1 = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage1 = taskWidgetPage1.openTaskList(); - taskWidgetPage1.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskTemplatePage taskTemplatePage2 = taskWidgetPage1.startTask(0); - TaskWidgetPage taskWidgetPage2 = taskTemplatePage2.finishIFrameReviewTask(); - WaitHelper - .assertTrueWithWait(() -> taskWidgetPage2.isElementDisplayed(By.cssSelector("[id$='task-config-command']"))); - } - - public void waitForTemplateRender() { - WaitHelper.waitForPresenceOfElementLocatedInFrame(this.getBrowser().getDriver(), "[class$='task-template-container']"); - } - - @Test - public void testTextOutIFrameChangeWithSkipTaskList() { - redirectToRelativeLink(IFRAME_TASK_URL); - waitForTemplateRender(); - TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage1 = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage1 = taskWidgetPage1.openTaskList(); - taskWidgetPage1.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskTemplatePage taskTemplatePage2 = taskWidgetPage1.startTask(0); - assertEquals("Review Request (Skip Tasklist in IFrame)", - taskTemplatePage2.getTaskNameOutsideIFrameWithSkipTaskList()); - } - - @Test - public void testShowCategoryInCaseByDefaultIframe() { - redirectToRelativeLink("InternalSupport/15B1EA24CCF377E8/saleAndInform.ivp"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskWidget = newDashboardPage.openTaskList(); - taskWidget.filterTasksInExpandedModeBy("sale department", 1); - TaskTemplatePage startTask = taskWidget.startTask(0); - startTask.openCaseInfo(); - startTask.switchToCaseInfoIframe(); - assertTrue(startTask.isCategoryColumnDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateTest.java deleted file mode 100644 index 0339d1ad8bf..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskTemplateTest.java +++ /dev/null @@ -1,153 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.TimeUnit; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.openqa.selenium.TimeoutException; - -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.Variable; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.NoteHistoryPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.WorkingTaskDialogPage; - -public class TaskTemplateTest extends BaseTest { - - private static final String ANNUAL_LEAVE_REQUEST_TASK ="Annual Leave Request"; - @Override - @Before - public void setup() { - super.setup(); - } - - @Test - public void testCaseDetailsTabDisplayed() { - createTestData(); - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - assertTrue("Case details is not displayed", taskTemplatePage.containsCaseDetails()); - } - - @Test - public void testAddingANote() { - createTestData(); - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - assertEquals(0, taskTemplatePage.countNoteItems()); - taskTemplatePage.addNewNote("Sample note message"); - assertEquals(1, taskTemplatePage.countNoteItems()); - } - - @Test - @Ignore - public void testOpeningFinishedTaskInHistoryArea() { - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - taskTemplatePage.openFinishedTaskInHistoryArea(); - - NoteHistoryPage caseHistoryPage = new NoteHistoryPage(); - - Awaitility.await().atMost(new Duration(5, TimeUnit.SECONDS)).until(() -> taskTemplatePage.countBrowserTab() > 1); - taskTemplatePage.switchLastBrowserTab(); - int numberOfNotes = 0; - try { - numberOfNotes = caseHistoryPage.countNotes(); - } catch (TimeoutException e) { // sometimes session is destroyed (don't know reason why!!!) so we cannot reach the page - System.out.println("Stop testShowCaseNoteHistory test here because session is destroyed"); - return ; - } - assertEquals(1, numberOfNotes); - } - - @Test - public void testOpeningRelatedTask() { - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestData(); - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - - getBrowser().getDriver().switchTo().defaultContent(); - TaskDetailsPage taskDetailsPage = taskTemplatePage.openRelatedTaskInList(ANNUAL_LEAVE_REQUEST_TASK); - assertEquals("Task: Annual Leave Request", taskDetailsPage.getTaskNameInDialog()); - - taskDetailsPage.clickBackButton(); - getBrowser().getDriver().switchTo().defaultContent(); - taskTemplatePage = new TaskTemplatePage(); - assertTrue(taskTemplatePage.countRelatedTasks() > 0); - } - - @Test - public void testOpeningDocumentUploading() { - createTestData(); - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - taskTemplatePage.openDocumentUploadingDialog(); - assertTrue(taskTemplatePage.isDocumentUploadingDialogDisplayed()); - } - - @Test - public void testLeaveWorkingTaskByClickingOnLogo() { - createTestData(); - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - taskTemplatePage.clickOnLogo(); - WorkingTaskDialogPage dialogPage = new WorkingTaskDialogPage(); - dialogPage.leaveTask(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidget.isTaskStateOpen(0)); - } - - @Test - public void testReserveWorkingTaskByClickingOnLogo() { - redirectToRelativeLink(simplePaymentUrl); - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - NewDashboardPage home = new NewDashboardPage(); - home.waitForPageLoaded(); - TaskTemplatePage taskTemplatePage = startATaskAndOpenCaseInfo(); - taskTemplatePage.clickOnLogo(); - WorkingTaskDialogPage dialogPage = new WorkingTaskDialogPage(); - dialogPage.reserveTask(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - Assert.assertTrue(taskWidget.isTaskStateReserved(0)); - } - - @Test - public void testResetTaskWhenStartSideStep() { - redirectToRelativeLink(createTestingCaseMapUrl); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - int latestTask = taskWidgetPage.countTasks() - 1; - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(latestTask); - taskTemplatePage.clickTaskActionMenu(); - taskTemplatePage.startSideStep(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidget.isTaskStateOpen(0)); - } - - private void createTestData() { - redirectToRelativeLink(createTestingTasksUrl); - } - - private TaskTemplatePage startATaskAndOpenCaseInfo() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(0); - taskTemplatePage.openCaseInfo(); - return taskTemplatePage; - } - - @Test - public void testShowCategoryColummnByDefault() { - createTestData(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskList = newDashboardPage.openTaskList(); - assertTrue(taskList.isCategoryColumnDisplayed()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskWidgetTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskWidgetTest.java deleted file mode 100644 index 8bf7cc53f75..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TaskWidgetTest.java +++ /dev/null @@ -1,242 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.DISABLE_TASK_COUNT; - -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TaskState; -import portal.guitest.common.TestAccount; -import portal.guitest.common.TestRole; -import portal.guitest.common.Variable; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskDetailsPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.page.UserProfilePage; - -public class TaskWidgetTest extends BaseTest { - - private static final String DISABLE_TASK_COUNT_SETTING = DISABLE_TASK_COUNT.getKey(); - private static final String GRANT_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL = - "portalKitTestHelper/14DE09882B540AD5/grantOnlyDelegateOwnTasksPermission.ivp"; - private static final String DENY_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL = - "portalKitTestHelper/14DE09882B540AD5/undoOnlyDelegateOwnTasksPermission.ivp"; - private static final String DENY_DESTROY_TASK_URL = "portalKitTestHelper/14DE09882B540AD5/denyDestroyTaskPermission.ivp"; - private static final String GRANT_DESTROY_TASK_URL = "portalKitTestHelper/14DE09882B540AD5/grantDestroyTaskPermission.ivp"; - - private static final String MATERNITY_LEAVE_REQUEST = "Maternity Leave Request"; - - private TaskDetailsPage taskDetailsPage; - - @Override - @Before - public void setup() { - super.setup(); - updateGlobalVariable(Variable.TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST.getKey(), "ACCESS_TASK_DETAILS"); - createTestingTasks(); - } - - @Test - public void testOpenRelatedCaseOfTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(0); - - String relatedCaseName = taskWidgetPage.getRelatedCase(); - CaseDetailsPage casePage = taskWidgetPage.openRelatedCaseOfTask(); - - String caseName = casePage.getCaseName(); - assertTrue(relatedCaseName.contains(caseName)); - } - - @SuppressWarnings("deprecation") - @Test - public void testReserveTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.sideStepMenuOnActionButton(0); - assertEquals(MATERNITY_LEAVE_REQUEST, taskWidgetPage.getNameOfTaskAt(0)); - taskWidgetPage.reserveTask(0); - taskWidgetPage.waitAjaxIndicatorDisappear(); - assertEquals(TaskState.OPEN, taskWidgetPage.getTaskState(0)); - taskWidgetPage.clickOnTaskStatesAndApply(List.of("Reserved")); - assertEquals(MATERNITY_LEAVE_REQUEST, taskWidgetPage.getNameOfTaskAt(0)); - taskWidgetPage.sideStepMenuOnActionButton(0); - taskWidgetPage.resetTask(0); - taskWidgetPage.waitAjaxIndicatorDisappear(); - assertEquals(TaskState.OPEN, taskWidgetPage.getTaskState(0)); - taskWidgetPage.clickOnTaskStatesAndApply(List.of("Reserved")); - assertEquals(0, taskWidgetPage.countTasks()); - taskWidgetPage.clickOnTaskStatesAndApply(List.of("Suspended")); - assertEquals(MATERNITY_LEAVE_REQUEST, taskWidgetPage.getNameOfTaskAt(0)); - } - - @Test - public void testStartButtonStatus() { - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Annual Leave Request"); - WaitHelper.assertTrueWithWait(() -> !taskWidgetPage.isTaskStartEnabled(0)); - taskWidgetPage.filterTasksInExpandedModeBy("Sick Leave Request"); - WaitHelper.assertTrueWithWait(() -> taskWidgetPage.isTaskStartEnabled(0)); - } - - @Test - public void testDisplayDelegateButton() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(GRANT_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertFalse(taskWidgetPage.isTaskDelegateOptionDisable("Sick Leave Request")); - assertTrue(taskWidgetPage.isTaskDelegateOptionDisable("Annual Leave Request")); - redirectToRelativeLink(DENY_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL); - } - - @Test - public void testDestroyTask() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(GRANT_DESTROY_TASK_URL); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Annual Leave Request"); - taskWidgetPage.sideStepMenuOnActionButton(0); - Assert.assertTrue(taskWidgetPage.isTaskDestroyEnabled(0)); - taskWidgetPage.destroyTask(0); - taskWidgetPage.confimDestruction(); - assertEquals(TaskState.DESTROYED, taskWidgetPage.getTaskState(0)); - redirectToRelativeLink(DENY_DESTROY_TASK_URL); - } - - @Test - public void testDisplayTaskAndCaseCategory() { - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(0); - assertEquals("Other Leave/Maternity", taskWidgetPage.getTaskCategory()); - assertEquals("Leave Request", taskWidgetPage.getCaseCategory()); - } - - @Test - public void testShowTaskCount() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.waitUntilTaskCountDifferentThanZero(); - assertEquals("In Task list, Task Count != 3", 3, taskWidgetPage.getTaskCount().intValue()); - } - - @Test - public void testDisableTaskCount() { - updatePortalSetting(DISABLE_TASK_COUNT_SETTING, "true"); - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals("In Task list, Task Count is disabled", null, taskWidgetPage.getTaskCount()); - } - - @Test - public void testBreadCrumb() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals("Tasks (3)", taskWidgetPage.getTextOfCurrentBreadcrumb()); - taskWidgetPage.goToHomeFromBreadcrumb(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals(true, newDashboardPage.isDisplayed()); - } - - @Test - public void testBreadCrumbInTaskDetail() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - assertEquals("Task: Maternity Leave Request", taskDetailsPage.getTextOfCurrentBreadcrumb()); - - taskDetailsPage.clickTaskListBreadCrumb(); - taskWidgetPage = new TaskWidgetPage(); - assertEquals(true, taskWidgetPage.isDisplayed()); - - taskDetailsPage = taskWidgetPage.openTaskDetails(0); - taskDetailsPage.goToHomeFromBreadcrumb(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals(true, newDashboardPage.isDisplayed()); - } - - @Test - public void testDelegateTask() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(TestRole.EVERYBODY_ROLE, taskWidgetPage.getResponsibleOfTaskAt(0)); - taskWidgetPage.openTaskDelegateDialog(0); - WaitHelper.assertTrueWithWait(() -> taskWidgetPage.isDelegateTypeSelectAvailable()); - taskWidgetPage.selectDelegateResponsible(TestAccount.HR_ROLE_USER.getFullName(), false); - assertEquals(TestAccount.HR_ROLE_USER.getFullName(), taskWidgetPage.getResponsibleOfTaskAt(0)); - - taskWidgetPage.openTaskDelegateDialog(0); - taskWidgetPage.selectDelegateResponsible(TestRole.HR_ROLE, true); - assertEquals(TestRole.HR_ROLE, taskWidgetPage.getResponsibleOfTaskAt(0)); - } - - @Test - public void testChangeTaskSortingOptions() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - - // Change sorting options - userProfilePage.selectTaskSortField("Priority"); - userProfilePage.selectTaskSortDirection("Sort ascending"); - newDashboardPage = userProfilePage.save(); - - // Check result - TaskWidgetPage taskWidgetPage = newDashboardPage.openTaskList(); - assertEquals("high", taskWidgetPage.getPriorityOfTask(0)); - assertEquals("low", taskWidgetPage.getPriorityOfTask(taskWidgetPage.countTasks() - 1)); - - // Change sorting options - userProfilePage = taskWidgetPage.openMyProfilePage(); - userProfilePage.selectTaskSortField("Name"); - userProfilePage.selectTaskSortDirection("Sort descending"); - newDashboardPage = userProfilePage.save(); - - // Check result - taskWidgetPage = newDashboardPage.openTaskList(); - assertEquals("Sick Leave Request", taskWidgetPage.getNameOfTaskAt(0)); - assertEquals("Annual Leave Request", taskWidgetPage.getNameOfTaskAt(taskWidgetPage.countTasks() - 1)); - } - - @Test - public void testExportToExcel() { - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - - taskWidgetPage.clickExportToExcelLink(); - - assertTrue(taskWidgetPage.isDownloadCompleted()); - } - - @Test - public void testStickySortTaskList() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.sortTaskListByColumn("Name / Description", 0, "task-name", "Annual Leave Request"); - String taskName = taskWidgetPage.getTaskListCustomCellValue(0, "task-name"); - assertTrue(StringUtils.equalsIgnoreCase("Annual Leave Request", taskName)); - taskWidgetPage.sortTaskListByColumn("Name / Description", 0, "task-name", "Sick Leave Request"); - taskWidgetPage.clickOnLogo(); - new NewDashboardPage(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskName = taskWidgetPage.getTaskListCustomCellValue(0, "task-name"); - assertTrue(StringUtils.equalsIgnoreCase("Sick Leave Request", taskName)); - - UserProfilePage userProfilePage = taskWidgetPage.openMyProfilePage(); - userProfilePage.selectTaskSortField("Priority"); - userProfilePage.selectTaskSortDirection("Sort ascending"); - NewDashboardPage newDashboardPage = userProfilePage.save(); - - taskWidgetPage = newDashboardPage.openTaskList(); - assertEquals("high", taskWidgetPage.getPriorityOfTask(0)); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TopbarTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TopbarTest.java deleted file mode 100644 index 1f8af208dfa..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/TopbarTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static portal.guitest.common.Variable.DEFAULT_THEME_MODE; -import static portal.guitest.common.Variable.ENABLE_SWITCH_THEME_BUTTON; -import static portal.guitest.common.Variable.LOGGED_IN_USER_FORMAT; - -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.NewDashboardPage; - -public class TopbarTest extends BaseTest { - - private static final String LOGGED_IN_USER_FORMAT_SETTING = LOGGED_IN_USER_FORMAT.getKey(); - private static final String DEFAULT_THEME_MODE_SETTING = DEFAULT_THEME_MODE.getKey(); - private static final String ENABLE_SWITCH_THEME_BUTTON_SETTING = ENABLE_SWITCH_THEME_BUTTON.getKey(); - - @Test - public void testLoggedInUserWithUsernameFormat() { - updatePortalSetting(LOGGED_IN_USER_FORMAT_SETTING, "USERNAME"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals("demo", newDashboardPage.getLoggedInUserFormat()); - } - - @Test - public void testLoggedInUserWithDisplayNameFormat() { - updatePortalSetting(LOGGED_IN_USER_FORMAT_SETTING, "DISPLAY_NAME"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals("Portal Demo User", newDashboardPage.getLoggedInUserFormat()); - } - - @Test - public void testLoggedInUserWithDisplayNameUsernameFormat() { - updatePortalSetting(LOGGED_IN_USER_FORMAT_SETTING, "DISPLAY_NAME_USERNAME"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals("Portal Demo User (demo)", newDashboardPage.getLoggedInUserFormat()); - } - - @Test - public void testLoggedInUserWithUsernameDisplayNameFormat() { - updatePortalSetting(LOGGED_IN_USER_FORMAT_SETTING, "USERNAME_DISPLAY_NAME"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals("demo (Portal Demo User)", newDashboardPage.getLoggedInUserFormat()); - } - - @Test - public void testThemeMode() { - updatePortalSetting(DEFAULT_THEME_MODE_SETTING, "Dark"); - updatePortalSetting(ENABLE_SWITCH_THEME_BUTTON_SETTING, "False"); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertTrue(newDashboardPage.isSwitchThemeToLightModeLinkIconDisplayed()); - assertTrue(newDashboardPage.isSwitchThemeLinkIconDisabled()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDeleteDocumentVisibilityTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDeleteDocumentVisibilityTest.java deleted file mode 100644 index f2e2cce7146..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDeleteDocumentVisibilityTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package portal.guitest.test; - -import static portal.guitest.common.Variable.HIDE_UPLOAD_DOCUMENT_FOR_DONE_CASE; - -import org.junit.Assert; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskWidgetPage; - -public class UploadDeleteDocumentVisibilityTest extends BaseTest { - - private NewDashboardPage newDashboardPage; - private CaseWidgetPage casePage; - private CaseDetailsPage caseDetailsPage; - private TaskWidgetPage taskWidgetPage; - - @Test - public void testShowUploadDeleteDocumentWhenHasDocumentOfInvolvedCaseWritePemission() { - createCaseAndUploadDocumentByUser(TestAccount.DEMO_USER); - - Assert.assertTrue(caseDetailsPage.isAddDocumentLinkDisplayed()); - Assert.assertTrue(caseDetailsPage.isDeleteDocumentButtonPresented()); - } - - @Test - public void testHideUploadDeleteDocumentWhenNotHasDocumentOfInvolvedCaseWritePemission() { - createCaseAndUploadDocumentByUser(TestAccount.DEMO_USER); - - denyDocumentOfInvolvedCaseWritePemissionFromCurrentUser(); - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("SupportTicket"); - - Assert.assertFalse(caseDetailsPage.isAddDocumentLinkDisplayed()); - Assert.assertFalse(caseDetailsPage.isDeleteDocumentButtonPresented()); - } - - @Test - public void testSettingHideUploadDeleteDocumentForDoneCase() { - createCaseAndUploadDocumentByUser(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.startTaskWithoutUI(0); - taskWidgetPage.openTaskList(); - updatePortalSetting(HIDE_UPLOAD_DOCUMENT_FOR_DONE_CASE.getKey(), "true"); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("SupportTicket"); - - Assert.assertFalse(caseDetailsPage.isAddDocumentLinkDisplayed()); - Assert.assertFalse(caseDetailsPage.isDeleteDocumentButtonPresented()); - } - - private void createCaseAndUploadDocumentByUser(TestAccount user) { - createTestingCaseContainOneTaskByUser(user); - uploadDocumentToTestingCaseByUser(); - } - - private void uploadDocumentToTestingCaseByUser() { - grantDocumentOfInvolvedCaseWritePemissionToCurrentUser(); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("SupportTicket"); - caseDetailsPage.uploadDocumentWithoutError(getAbsolutePathToTestFile("test-no-files-no-js.pdf")); - } - - private void createTestingCaseContainOneTaskByUser(TestAccount user) { - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - initNewDashboardPage(user); - redirectToRelativeLink(createTestingCaseContainOneTask); - } - - private void initNewDashboardPage(TestAccount account) { - login(account); - newDashboardPage = new NewDashboardPage(); - } - - private String getAbsolutePathToTestFile(String fileName) { - return System.getProperty("user.dir") + "\\resources\\testFile\\" + fileName; - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDocumentTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDocumentTest.java deleted file mode 100644 index fbfe0cb1b72..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UploadDocumentTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; -import static portal.guitest.common.FileHelper.getAbsolutePathToTestFile; -import static portal.guitest.common.Variable.ENABLE_SCRIPT_CHECKING_FOR_UPLOADED_DOCUMENT; -import static portal.guitest.common.Variable.UPLOAD_DOCUMENT_WHITELIST_EXTENSION; - -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.Sleeper; -import portal.guitest.common.TestAccount; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; - -public class UploadDocumentTest extends BaseTest{ - - private NewDashboardPage newDashboardPage; - private CaseWidgetPage casePage; - private CaseDetailsPage caseDetailsPage; - - @Override - @Before - public void setup() { - super.setup(); - createTestingTasks(); - } - - @Test - public void uploadNormalDocument() { - initNewDashboardPage(TestAccount.ADMIN_USER); - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - int numberOfDocument = caseDetailsPage.countNumberOfDocument(); - caseDetailsPage.uploadDocumentWithoutError(getAbsolutePathToTestFile("test-no-files-no-js.pdf")); - assertEquals(numberOfDocument + 1, caseDetailsPage.countNumberOfDocument()); - } - - @Test - public void uploadScriptDocumentAndGetError() { - enableScriptCheckingInPortalSetting(); - initNewDashboardPage(TestAccount.ADMIN_USER); - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - String error = caseDetailsPage.uploadDocumentWithError(getAbsolutePathToTestFile("test-with-macro.doc")); - assertEquals("This file is not allowed to upload because it contains some script!", error); - Sleeper.sleep(1000); // make Firefox passed, maybe a bug of Portal - - error = caseDetailsPage.uploadDocumentWithError(getAbsolutePathToTestFile("test-with-macro.xls")); - assertEquals("This file is not allowed to upload because it contains some script!", error); - Sleeper.sleep(1000);// make Firefox passed, maybe a bug of Portal - - error = caseDetailsPage.uploadDocumentWithError(getAbsolutePathToTestFile("test-no-files-with-js.pdf")); - assertEquals("This file is not allowed to upload because it contains some script!", error); - disableScriptCheckingInPortalSetting(); - } - - @Test - public void uploadUnsupportedFileType(){ - enableScriptCheckingInPortalSetting(); - initNewDashboardPage(TestAccount.ADMIN_USER); - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - String error = caseDetailsPage.uploadDocumentWithError(getAbsolutePathToTestFile("unsupportedExtension.abc")); - assertEquals("This file type is not accepted!", error); - disableScriptCheckingInPortalSetting(); - } - - @Test - public void uploadDocumentAndCheckDocumentName() { - final String pdfFile = "test-no-files-no-js.pdf"; - final String wordFile = "test-ms-word-extension.doc"; - final String unsupportFile = "unsupportedExtension.abc"; - - updateFileExtensionWhiteListInPortalSetting(); - initNewDashboardPage(TestAccount.ADMIN_USER); - - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - - caseDetailsPage.uploadDocumentWithoutError(getAbsolutePathToTestFile(pdfFile)); - Assert.assertTrue(isCorrectIconExtension(pdfFile, "si si-office-file-pdf-1")); - - caseDetailsPage.uploadDocumentWithoutError(getAbsolutePathToTestFile(wordFile)); - Assert.assertTrue(isCorrectIconExtension(wordFile, "si si-office-file-doc-1")); - - caseDetailsPage.uploadDocumentWithoutError(getAbsolutePathToTestFile(unsupportFile)); - Assert.assertTrue(isCorrectIconExtension(unsupportFile, "si si-common-file-empty")); - } - - private boolean isCorrectIconExtension(String fileName, String iconClass) { - final String caseDetailDocumentClass = "case-details-document-download-icon"; - List documentItems = caseDetailsPage.findDocumentItemInCaseDetailsDocumentTable(); - for (WebElement document:documentItems) { - String uploadedFileName = document.findElement(By.cssSelector(".js-document-name")).getText(); - if (uploadedFileName.equalsIgnoreCase(fileName)) { - String symbol = document.findElement(By.cssSelector("." + caseDetailDocumentClass)).getAttribute("class"); - assertEquals(symbol, iconClass.concat(StringUtils.SPACE.concat(caseDetailDocumentClass))); - return true; - } - } - return false; - } - - @Test - public void addUnspportedFileTypeToSettingAndUploadFile() { - updateFileExtensionWhiteListInPortalSetting(); - initNewDashboardPage(TestAccount.ADMIN_USER); - casePage = newDashboardPage.openCaseList(); - caseDetailsPage = casePage.openDetailsOfCaseHasName("Leave Request"); - int numberOfDocument = caseDetailsPage.countNumberOfDocument(); - caseDetailsPage.uploadDocumentWithoutError(getAbsolutePathToTestFile("unsupportedExtension.abc")); - assertEquals(numberOfDocument + 1, caseDetailsPage.countNumberOfDocument()); - } - - private void initNewDashboardPage(TestAccount account) { - login(account); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - newDashboardPage = new NewDashboardPage(); - } - - private void updateFileExtensionWhiteListInPortalSetting() { - updatePortalSetting(UPLOAD_DOCUMENT_WHITELIST_EXTENSION.getKey(), ", abc, pdf, doc"); - } - - private void disableScriptCheckingInPortalSetting() { - updatePortalSetting(ENABLE_SCRIPT_CHECKING_FOR_UPLOADED_DOCUMENT.getKey(), "false"); - } - - private void enableScriptCheckingInPortalSetting() { - updatePortalSetting(ENABLE_SCRIPT_CHECKING_FOR_UPLOADED_DOCUMENT.getKey(), "true"); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserHomepageTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserHomepageTest.java deleted file mode 100644 index f2dd2ac4d97..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserHomepageTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package portal.guitest.test; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.TestAccount; -import portal.guitest.page.CaseWidgetPage; -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.UserProfilePage; - -public class UserHomepageTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - login(TestAccount.ADMIN_USER); - } - - @Test - public void testHomepageInUserProfile() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - UserProfilePage profilePage = newDashboardPage.openMyProfilePage(); - profilePage.changeNewDashboardPageToCase(); - profilePage.saveWithoutWaitingNavigation(); - new CaseWidgetPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserSelectionComponentTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserSelectionComponentTest.java deleted file mode 100644 index 6f07c561d15..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/test/UserSelectionComponentTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package portal.guitest.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.UserSelectionComponentPage; - -public class UserSelectionComponentTest extends BaseTest { - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLink(userSelectionComponentShowcaseUrl); - } - - @Test - public void testNormalUserSelection() { - UserSelectionComponentPage userSelectionComponentPage = new UserSelectionComponentPage(); - String value = userSelectionComponentPage.selectFirstItemForNormalUserSelectionComponent("Backend Developer 1"); - assertEquals(value, userSelectionComponentPage.getNormalUserSelection()); - } - - @Test - public void testFloatingLabelUserSelection() { - UserSelectionComponentPage userSelectionComponentPage = new UserSelectionComponentPage(); - String value = userSelectionComponentPage.selectFirstItemForFloatingLabelUserSelectionComponent("Backend Developer 1"); - assertEquals(value, userSelectionComponentPage.getFloatingLabelUserSelection()); - } - - @Test - public void testAjaxEventUserSelection() { - UserSelectionComponentPage userSelectionComponentPage = new UserSelectionComponentPage(); - String value = userSelectionComponentPage.selectFirstItemForFloatingLabelUserSelectionComponent("Backend Developer 1"); - assertEquals(value, userSelectionComponentPage.getFloatingLabelUserSelection()); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/CaseMapTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/CaseMapTest.java deleted file mode 100644 index d993debd3f0..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/CaseMapTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package portal.guitest.userexample.test; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.NavigationHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.userexamples.page.CaseMapPage; -import portal.guitest.userexamples.page.UserExamplesEndPage; - -public class CaseMapTest extends BaseTest { - - private static final String CREATE_CONTRACT = "Create Contract"; - private static final String CASE_MAP_URL = "/portal-user-examples/70765b37-a3e8-418a-a8d5-c2b3a539408e.icm"; - private static final String VERIFY_PERSONAL_DATA = "Verify Personal Data"; - private static final String INTERNAL_SOLVENCY_CHECK = "Internal Solvency Check"; - private static final String APPROVAL_LEVEL_1 = "Approve Level 1"; - private static final String APPROVAL_LEVEL_2 = "Approve Level 2"; - private CaseMapPage caseMapPage; - private TaskWidgetPage taskWidgetPage; - - @Override - @Before - public void setup() { - super.setup(); - redirectToRelativeLinkWithEmbedInFrame(CASE_MAP_URL); - new MainMenuPage().switchToIFrameOfTask(); - } - - @Test - public void testCaseMapApprovalWorkflow() { - caseMapPage = new CaseMapPage(); - caseMapPage.inputFields("John", "Jack", "1.1.2019", "VN", "20000", "To buy a new car", "80000", "100000"); - caseMapPage.clickSubmitRequestButton(); - startTaskByTaskName(VERIFY_PERSONAL_DATA); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - caseMapPage.inputVerifierComment("Ok"); - caseMapPage.clickSubmitButton(); - startTaskByTaskName(INTERNAL_SOLVENCY_CHECK); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - Assert.assertEquals("Ok", caseMapPage.getVerifierComment()); - caseMapPage.inputInternalCreditComment("Pass"); - caseMapPage.clickSubmitButton(); - startTaskByTaskName(APPROVAL_LEVEL_1); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - Assert.assertEquals("Ok", caseMapPage.getVerifierComment()); - Assert.assertEquals("Pass", caseMapPage.getInternalCreditComment()); - caseMapPage.clickApproveButton(); - startTaskByTaskName(APPROVAL_LEVEL_2); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - Assert.assertEquals("Ok", caseMapPage.getVerifierComment()); - Assert.assertEquals("Pass", caseMapPage.getInternalCreditComment()); - caseMapPage.clickApproveButton(); - startTaskByTaskName(CREATE_CONTRACT); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - UserExamplesEndPage userExamplesEndPage = caseMapPage.clickSubmitContractButton(); - CaseDetailsPage caseDetailsPage = userExamplesEndPage.goToCaseDetail(); - Assert.assertEquals("Lending", caseDetailsPage.getCaseName()); - } - - @Test - public void testCaseMapRejectedWorkflow() { - caseMapPage = new CaseMapPage(); - caseMapPage.inputFields("John", "Jack", "1.1.2019", "VN", "20000", "To buy a new car", "80000", "100000"); - caseMapPage.clickSubmitRequestButton(); - startTaskByTaskName(VERIFY_PERSONAL_DATA); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - caseMapPage.inputVerifierComment("Ok"); - caseMapPage.clickSubmitButton(); - startTaskByTaskName(INTERNAL_SOLVENCY_CHECK); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - Assert.assertEquals("Ok", caseMapPage.getVerifierComment()); - caseMapPage.inputInternalCreditComment("Fail"); - caseMapPage.clickSubmitButton(); - startTaskByTaskName(APPROVAL_LEVEL_1); - caseMapPage.switchToIFrameOfTask(); - assertInputData(); - Assert.assertEquals("Ok", caseMapPage.getVerifierComment()); - Assert.assertEquals("Fail", caseMapPage.getInternalCreditComment()); - caseMapPage.clickRejectButton(); - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.filterTasksInExpandedModeBy(APPROVAL_LEVEL_2, 0); - Assert.assertEquals(0, taskWidgetPage.countTasks()); - } - - private void assertInputData() { - Assert.assertEquals("John", caseMapPage.getCustomerLastName()); - Assert.assertEquals("Jack", caseMapPage.getCustomerFirstName()); - Assert.assertEquals("VN", caseMapPage.getCountry()); - Assert.assertEquals("20000", caseMapPage.getAmount()); - Assert.assertEquals("To buy a new car", caseMapPage.getReason()); - Assert.assertEquals("80000", caseMapPage.getSalary()); - Assert.assertEquals("100000", caseMapPage.getOtherCredits()); - } - - @Test - public void testCollectPersonalDataValidation() { - caseMapPage = new CaseMapPage(); - caseMapPage.switchToIFrameOfTask(); - caseMapPage.inputFields("", "", "", "", "", "", "", ""); - Assert.assertEquals( - "First name: Value is required.," - + "Country: Value is required.," - + "Amount (SFr.): Value is required.," - + "Yearly salary: Value is required.," - + "Amount of other open credits (SFr.): Value is required.", - caseMapPage.clickSubmitAndGetValidationMsg()); - } - - private void startTaskByTaskName(String taskname) { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy(taskname); - taskWidgetPage.startTask(0); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/ExampleOverviewTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/ExampleOverviewTest.java deleted file mode 100644 index aae2525bcf1..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/ExampleOverviewTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package portal.guitest.userexample.test; - -import static org.junit.Assert.assertEquals; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.page.ExampleOverviewPage; -import portal.guitest.page.LeaveRequestOverviewPage; -import portal.guitest.page.LendingDetailPage; -import portal.guitest.page.LendingOverviewPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.userexamples.page.CaseMapPage; -import portal.guitest.userexamples.page.LeaveRequestPage; - -public class ExampleOverviewTest extends BaseTest { - public final static String PORTAL_EXAMPLES_PROCESS_CHAIN = "portal-user-examples/17236DB1D3DA14C0/userExampleGuide.ivp"; - private ExampleOverviewPage exampleOverviewPage; - - @Before - @Override - public void setup() { - super.setup(); - redirectToRelativeLinkWithEmbedInFrame(PORTAL_EXAMPLES_PROCESS_CHAIN); - new MainMenuPage().switchToIFrameOfTask(); - exampleOverviewPage = new ExampleOverviewPage(); - } - - @Test - public void testOverviewLeaveRequest() { - LeaveRequestOverviewPage leaveRequestOverview = exampleOverviewPage.openLeaveRequestOverview(); - leaveRequestOverview.switchToIFrameOfTask(); - assertEquals("Leave Request", leaveRequestOverview.getHearText()); - assertEquals("Creation", leaveRequestOverview.getStepName(0)); - assertEquals("Approval", leaveRequestOverview.getStepName(1)); - assertEquals("Summary", leaveRequestOverview.getStepName(2)); - - LeaveRequestPage leaveRequest = leaveRequestOverview.start(); - Assert.assertEquals("Create leave request", leaveRequest.getPageTitle()); - } - - @Test - public void testOverviewLending() { - LendingOverviewPage lendingOverview = exampleOverviewPage.openLendingOverview(); - assertEquals("Lending (Case Map)", lendingOverview.getHearText()); - assertEquals("Identification", lendingOverview.getStageName(0)); - assertEquals("Credit rating", lendingOverview.getStageName(1)); - assertEquals("Approval", lendingOverview.getStageName(2)); - - LendingDetailPage creditRating = lendingOverview.navigateToStageDetail(1); - assertEquals("Lending (Case Map)", creditRating.getHearText()); - assertEquals("Stage 2 - Credit rating", creditRating.getStageName()); - assertEquals("Check Company Register", creditRating.getProcessName(0)); - assertEquals("Internal Solvency Check", creditRating.getProcessName(1)); - assertEquals("External Solvency Check", creditRating.getSideStepName(0)); - - lendingOverview = creditRating.navigateToLendingOverview(); - assertEquals("Lending (Case Map)", lendingOverview.getHearText()); - - CaseMapPage caseMapPage = lendingOverview.startLendingCase(); - assertEquals("Credit Request", caseMapPage.getHeader()); - } - - @Test - public void testOverviewDetailNavigate() { - LendingOverviewPage lendingOverview = exampleOverviewPage.openLendingOverview(); - - LendingDetailPage identification = lendingOverview.navigateToStageDetail(0); - - LendingDetailPage creditRating = identification.navigateToNextDetail(); - assertEquals("Stage 2 - Credit rating", creditRating.getStageName()); - - LendingDetailPage approval = creditRating.navigateToNextDetail(); - assertEquals("Stage 3 - Approval", approval.getStageName()); - - creditRating = approval.navigateToPreviousDetail(); - assertEquals("Stage 2 - Credit rating", creditRating.getStageName()); - - identification = creditRating.navigateToPreviousDetail(); - assertEquals("Stage 1 - Identification", identification.getStageName()); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/LeaveRequestTest.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/LeaveRequestTest.java deleted file mode 100644 index e19edea34da..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexample/test/LeaveRequestTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package portal.guitest.userexample.test; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Locale; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import portal.guitest.common.BaseTest; -import portal.guitest.common.DateTimePattern; -import portal.guitest.common.NavigationHelper; -import portal.guitest.common.TestAccount; -import portal.guitest.common.WaitHelper; -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.MainMenuPage; -import portal.guitest.page.TaskWidgetPage; -import portal.guitest.userexamples.page.LeaveRequestPage; -import portal.guitest.userexamples.page.UserExamplesEndPage; - -public class LeaveRequestTest extends BaseTest { - private static final String LEAVE_REQUEST_START_LINK = "portal-user-examples/170321BD7F5539D6/start.ivp"; - private LeaveRequestPage leaveRequestPage; - private TaskWidgetPage taskWidgetPage; - - @Before - @Override - public void setup() { - super.setup(); - } - - @Test - public void testLeaveRequestValidation() { - leaveRequestPage = startLeaveRequestProcess(); - Assert.assertEquals("Leave type: This field is required" - + ",From: This field is required," - + "To: This field is required," - + "Approver: This field is required," - + "Requester comment: This field is required", - leaveRequestPage.clickSubmitAndGetValidationMsg()); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - String yesterday = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN)); - leaveRequestPage.enterLeaveRequestInformation("Maternity Leave", today, yesterday, TestAccount.DEMO_USER.getFullName(), "requester comment"); - Assert.assertEquals("'To' must be later than 'From'.", leaveRequestPage.clickSubmitAndGetValidationMsg()); - } - - @Test - public void testApproveScenario() { - leaveRequestPage = startLeaveRequestProcess(); - Assert.assertEquals("Create leave request", leaveRequestPage.getPageTitle()); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN, new Locale("en"))); - String yesterday = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN, new Locale("en"))); - leaveRequestPage.waitForIFrameContentVisible(); - leaveRequestPage.enterLeaveRequestInformation("Maternity Leave", yesterday, today, TestAccount.ADMIN_USER.getFullName(), "requester comment"); - leaveRequestPage.clickSubmitButton(); - leaveRequestPage.clickOnLogout(); - login(TestAccount.ADMIN_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.startTask(0); - taskWidgetPage.switchToIFrameOfTask(); - WaitHelper.assertTrueWithWait(() -> "Approval".equals(leaveRequestPage.getPageTitle())); - leaveRequestPage.enterApproverComment("Approved"); - leaveRequestPage.clickApproveBtn(); - leaveRequestPage.clickOnLogout(); - login(TestAccount.DEMO_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Your leave request is approved"); - taskWidgetPage.startTask(0); - taskWidgetPage.switchToIFrameOfTask(); - WaitHelper.assertTrueWithWait(() -> "Approval Result".equals(leaveRequestPage.getPageTitle())); - UserExamplesEndPage userExamplesEndPage = leaveRequestPage.finishLeaveRequest(); - CaseDetailsPage caseDetailsPage = userExamplesEndPage.goToCaseDetail(); - Assert.assertEquals("Leave Request", caseDetailsPage.getCaseName()); - } - - @Test - public void testRejectScenario() { - leaveRequestPage = startLeaveRequestProcess(); - Assert.assertEquals("Create leave request", leaveRequestPage.getPageTitle()); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN, new Locale("en"))); - String yesterday = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern(DateTimePattern.DATE_TIME_PATTERN, new Locale("en"))); - leaveRequestPage.enterLeaveRequestInformation("Maternity Leave", yesterday, today, TestAccount.ADMIN_USER.getFullName(), "requester comment"); - leaveRequestPage.clickSubmitButton(); - leaveRequestPage.clickOnLogout(); - login(TestAccount.ADMIN_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.startTask(0); - taskWidgetPage.switchToIFrameOfTask(); - WaitHelper.assertTrueWithWait(() -> "Approval".equals(leaveRequestPage.getPageTitle())); - leaveRequestPage.enterApproverComment("Rejected"); - leaveRequestPage.clickRejectBtn(); - leaveRequestPage.clickOnLogout(); - login(TestAccount.DEMO_USER); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("Your leave request is rejected"); - taskWidgetPage.startTask(0); - taskWidgetPage.switchToIFrameOfTask(); - WaitHelper.assertTrueWithWait(() -> "Approval Result".equals(leaveRequestPage.getPageTitle())); - } - - private LeaveRequestPage startLeaveRequestProcess() { - redirectToRelativeLinkWithEmbedInFrame(LEAVE_REQUEST_START_LINK); - new MainMenuPage().switchToIFrameOfTask(); - return new LeaveRequestPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/CaseMapPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/CaseMapPage.java deleted file mode 100644 index bcaeffacee2..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/CaseMapPage.java +++ /dev/null @@ -1,151 +0,0 @@ -package portal.guitest.userexamples.page; - -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; - -import portal.guitest.page.NewDashboardPage; -import portal.guitest.page.TaskTemplatePage; -import portal.guitest.page.TaskWidgetPage; - -public class CaseMapPage extends TaskTemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('form:first-name')"; - } - - public void inputFields(String lastName, String firstName, String birthDate, String country, String amount, String reason, - String salary, String otherCredit) { - waitForIFrameContentVisible(); - type(By.id("form:last-name"), lastName); - type(By.id("form:first-name"), firstName); - typeBirthDay(birthDate); - type(By.id("form:country"), country); - type(By.id("form:amount"), amount); - type(By.id("form:reason"), reason); - type(By.id("form:salary"), salary); - type(By.id("form:amount-of-other-credits"), otherCredit); - } - - private void typeBirthDay(String text) { - WebElement datePicker = findElementByCssSelector("input[id='form:birth-date_input']"); - datePicker.sendKeys(Keys.chord(Keys.CONTROL, "a")); - datePicker.sendKeys(Keys.BACK_SPACE); - datePicker.sendKeys(text); - } - - public void inputVerifierComment(String comment) { - type(By.id("form:verifier-comment"), comment); - } - - public void inputExternalCreditComment(String comment) { - type(By.id("form:external-comment"), comment); - } - - public void inputInternalCreditComment(String comment) { - type(By.id("form:internal-comment"), comment); - } - - public String getCustomerLastName() { - return findElementByCssSelector("input[id$='last-name']").getAttribute("value"); - } - - public String getCustomerFirstName() { - return findElementByCssSelector("input[id$='first-name']").getAttribute("value"); - } - - public String getCountry() { - return findElementByCssSelector("input[id$='customer-country']").getAttribute("value"); - } - - public String getAmount() { - return findElementByCssSelector("input[id$='request-amount']").getAttribute("value"); - } - - public String getSalary() { - return findElementByCssSelector("input[id$='request-salary']").getAttribute("value"); - } - - public String getReason() { - return findElementByCssSelector("input[id$='request-reason']").getAttribute("value"); - } - - public String getOtherCredits() { - return findElementByCssSelector("input[id$='request-amount-of-other-credits']").getAttribute("value"); - } - - public String getVerifierComment() { - return findElementByCssSelector("textarea[id$='verifier-comment']").getText(); - } - - public String getInternalCreditComment() { - return findElementByCssSelector("textarea[id$='internal-comment']").getText(); - } - - @SuppressWarnings("deprecation") - public String clickSubmitAndGetValidationMsg() { - clickByCssSelector("button[id$='submit-request']"); - waitForElementDisplayedByCssSelector(".ui-messages-error-icon"); - waitAjaxIndicatorDisappear(); - return getValidationMsg(); - } - - public String getValidationMsg() { - List messages = findListElementsByCssSelector(("span.ui-messages-error-summary")); - return StringUtils.join(messages.stream().map(WebElement::getText).collect(Collectors.toList()), ","); - } - - public void waitUntilCaseMapPageDisplayed() { - waitForElementDisplayed(By.id("form:submit-request"), true); - } - - @Override - public TaskWidgetPage clickSubmitButton() { - clickByCssSelector("button[id$='submit-button']"); - switchToDefaultContent(); - return new TaskWidgetPage(); - } - - public NewDashboardPage clickSubmitRequestButton() { - clickByCssSelector("button[id$='submit-request']"); - switchToDefaultContent(); - return new NewDashboardPage(); - } - - public TaskWidgetPage clickApproveButton() { - clickByCssSelector("button[id$='form:approval-button']"); - switchToDefaultContent(); - return new TaskWidgetPage(); - } - - public TaskWidgetPage clickRejectButton() { - clickByCssSelector("button[id$='form:rejected-button']"); - switchToDefaultContent(); - return new TaskWidgetPage(); - } - - public UserExamplesEndPage clickSubmitContractButton() { - clickByCssSelector("button[id$='submit-contract-button']"); - switchToDefaultContent(); - return new UserExamplesEndPage(); - } - - public String getTitle() { - return findElementByCssSelector("[id$='title']").getText(); - } - - public String getHeader() { - return findElementByCssSelector("#header").getText(); - } - - public TaskWidgetPage clickSubmitButtonAndBackToTaskList() { - clickByCssSelector("button[id$='submit-button']"); - switchToDefaultContent(); - return new TaskWidgetPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/LeaveRequestPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/LeaveRequestPage.java deleted file mode 100644 index 90608532fab..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/LeaveRequestPage.java +++ /dev/null @@ -1,104 +0,0 @@ -package portal.guitest.userexamples.page; - -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebElement; - -import portal.guitest.common.WaitHelper; -import portal.guitest.page.TaskTemplateIFramePage; -import portal.guitest.page.TaskWidgetPage; - -public class LeaveRequestPage extends TaskTemplateIFramePage { - - @Override - protected String getLoadedLocator() { - return "id('leave-request:button-submit')"; - } - - public void clickSubmitLeaveRequest() { - click(By.id("leave-request:button-submit")); - } - - @SuppressWarnings("deprecation") - public String clickSubmitAndGetValidationMsg() { - int numberOfErrors = findListElementsByCssSelector(("span.ui-messages-error-summary")).size(); - clickSubmitLeaveRequest(); - WaitHelper.assertTrueWithWait( - () -> findListElementsByCssSelector(("span.ui-messages-error-summary")).size() != numberOfErrors); - waitAjaxIndicatorDisappear(); - return getValidationMsg(); - } - - public String getValidationMsg() { - List messages = findListElementsByCssSelector(("span.ui-messages-error-summary")); - return StringUtils.join(messages.stream().map(WebElement::getText).collect(Collectors.toList()), ","); - } - - public void enterLeaveRequestInformation(String leaveType, String from, String to, String approver, String requesterComment) { - selectLeaveType(leaveType); - type(findElementById("leave-request:from_input"), from); - closePanelDatePicker(findElementById("leave-request:from_panel")); - type(findElementById("leave-request:to_input"), to); - closePanelDatePicker(findElementById("leave-request:to_panel")); - enterKeys(findElementById("leave-request:requester-comment"), requesterComment); - selectApprover(approver); - } - - private void closePanelDatePicker(WebElement element) { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("arguments[0].style.display = 'none'", element); - } - - public void enterApproverComment(String approverComment) { - enterKeys(findElementById("leave-request:approver-comment"), approverComment); - } - - public TaskWidgetPage clickApproveBtn() { - click(By.id("leave-request:approved-btn")); - switchToDefaultContent(); - return new TaskWidgetPage(); - } - - public TaskWidgetPage clickRejectBtn() { - click(By.id("leave-request:rejected-btn")); - switchToDefaultContent(); - return new TaskWidgetPage(); - } - - public UserExamplesEndPage finishLeaveRequest() { - click(By.id("leave-request:finish-btn")); - switchToDefaultContent(); - return new UserExamplesEndPage(); - } - - private void selectLeaveType(String leaveType) { - clickByCssSelector("#leave-request\\:leave-type_label"); - String leaveTypeSelector = "li[data-label='" + leaveType + "']"; - waitForElementDisplayed(By.cssSelector(leaveTypeSelector), true); - clickByCssSelector(leaveTypeSelector); - } - - private void selectApprover(String approver) { - findElementById("leave-request:approver_label").click(); - String approverSelector = "li[data-label='" + approver + "']"; - waitForElementDisplayed(By.cssSelector(approverSelector), true); - clickByCssSelector(approverSelector); - } - - public void waitUntilLeaveRequestPageDisplayed() { - waitForElementDisplayed(By.id("leave-request:button-submit"), true); - } - - public void fulfillAndSendMaternityLeaveRequest() { - type(findElementById("leave-request:from_input"), "Jun 23, 2023 10:37"); - type(findElementById("leave-request:to_input"), "Jun 24, 2023 10:37"); - type(findElementById("leave-request:fullname"), "John Doe"); - type(findElementById("leave-request:substitute"), "John Wick"); - click(By.id("leave-request:button-submit")); - } - -} diff --git a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/UserExamplesEndPage.java b/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/UserExamplesEndPage.java deleted file mode 100644 index 8429d63d782..00000000000 --- a/AxonIvyPortal/PortalTest/src_test/portal/guitest/userexamples/page/UserExamplesEndPage.java +++ /dev/null @@ -1,19 +0,0 @@ -package portal.guitest.userexamples.page; - -import org.openqa.selenium.By; - -import portal.guitest.page.CaseDetailsPage; -import portal.guitest.page.TemplatePage; - -public class UserExamplesEndPage extends TemplatePage { - - @Override - protected String getLoadedLocator() { - return "id('form:go-to-case-detail')"; - } - - public CaseDetailsPage goToCaseDetail() { - click(By.id("form:go-to-case-detail")); - return new CaseDetailsPage(); - } -} diff --git a/AxonIvyPortal/PortalTest/zip.xml b/AxonIvyPortal/PortalTest/zip.xml deleted file mode 100644 index cba2cd6f4a1..00000000000 --- a/AxonIvyPortal/PortalTest/zip.xml +++ /dev/null @@ -1,16 +0,0 @@ - - zip - false - - - zip - - - - target/screenshots - - - - diff --git a/AxonIvyPortal/PortalTest/jmeter/chat-cluster-try-out/portal_walkthrough_testplan.jmx b/AxonIvyPortal/portal-selenium-test/jmeter/chat-cluster-try-out/portal_walkthrough_testplan.jmx similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/chat-cluster-try-out/portal_walkthrough_testplan.jmx rename to AxonIvyPortal/portal-selenium-test/jmeter/chat-cluster-try-out/portal_walkthrough_testplan.jmx diff --git a/AxonIvyPortal/PortalTest/jmeter/chat-cluster-try-out/test.properties b/AxonIvyPortal/portal-selenium-test/jmeter/chat-cluster-try-out/test.properties similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/chat-cluster-try-out/test.properties rename to AxonIvyPortal/portal-selenium-test/jmeter/chat-cluster-try-out/test.properties diff --git a/AxonIvyPortal/PortalTest/jmeter/configuration/variables.Portal.Dashboard.json b/AxonIvyPortal/portal-selenium-test/jmeter/configuration/variables.Portal.Dashboard.json similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/configuration/variables.Portal.Dashboard.json rename to AxonIvyPortal/portal-selenium-test/jmeter/configuration/variables.Portal.Dashboard.json diff --git a/AxonIvyPortal/PortalTest/jmeter/data/single_admin_user_local.csv b/AxonIvyPortal/portal-selenium-test/jmeter/data/single_admin_user_local.csv similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/data/single_admin_user_local.csv rename to AxonIvyPortal/portal-selenium-test/jmeter/data/single_admin_user_local.csv diff --git a/AxonIvyPortal/PortalTest/jmeter/data/single_admin_user_server.csv b/AxonIvyPortal/portal-selenium-test/jmeter/data/single_admin_user_server.csv similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/data/single_admin_user_server.csv rename to AxonIvyPortal/portal-selenium-test/jmeter/data/single_admin_user_server.csv diff --git a/AxonIvyPortal/PortalTest/jmeter/data/single_normal_user_local.csv b/AxonIvyPortal/portal-selenium-test/jmeter/data/single_normal_user_local.csv similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/data/single_normal_user_local.csv rename to AxonIvyPortal/portal-selenium-test/jmeter/data/single_normal_user_local.csv diff --git a/AxonIvyPortal/PortalTest/jmeter/data/single_normal_user_server.csv b/AxonIvyPortal/portal-selenium-test/jmeter/data/single_normal_user_server.csv similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/data/single_normal_user_server.csv rename to AxonIvyPortal/portal-selenium-test/jmeter/data/single_normal_user_server.csv diff --git a/AxonIvyPortal/PortalTest/jmeter/data/users_local.csv b/AxonIvyPortal/portal-selenium-test/jmeter/data/users_local.csv similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/data/users_local.csv rename to AxonIvyPortal/portal-selenium-test/jmeter/data/users_local.csv diff --git a/AxonIvyPortal/PortalTest/jmeter/data/users_server.csv b/AxonIvyPortal/portal-selenium-test/jmeter/data/users_server.csv similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/data/users_server.csv rename to AxonIvyPortal/portal-selenium-test/jmeter/data/users_server.csv diff --git a/AxonIvyPortal/PortalTest/jmeter/portal_walkthrough_testplan.jmx b/AxonIvyPortal/portal-selenium-test/jmeter/portal_walkthrough_testplan.jmx similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/portal_walkthrough_testplan.jmx rename to AxonIvyPortal/portal-selenium-test/jmeter/portal_walkthrough_testplan.jmx diff --git a/AxonIvyPortal/PortalTest/jmeter/test.properties b/AxonIvyPortal/portal-selenium-test/jmeter/test.properties similarity index 100% rename from AxonIvyPortal/PortalTest/jmeter/test.properties rename to AxonIvyPortal/portal-selenium-test/jmeter/test.properties diff --git a/AxonIvyPortal/PortalTest/resources/GeckoFireFoxDriver.exe b/AxonIvyPortal/portal-selenium-test/resources/GeckoFireFoxDriver.exe similarity index 100% rename from AxonIvyPortal/PortalTest/resources/GeckoFireFoxDriver.exe rename to AxonIvyPortal/portal-selenium-test/resources/GeckoFireFoxDriver.exe diff --git a/build/create-release/Jenkinsfile b/build/create-release/Jenkinsfile index bf417c1c5e6..e82ac1d08e3 100644 --- a/build/create-release/Jenkinsfile +++ b/build/create-release/Jenkinsfile @@ -34,7 +34,7 @@ pipeline { powershell ''' #find all pom file of portal project and change their versions and their portal dependencies to releaseVersion $utf8WithoutBom = New-Object System.Text.UTF8Encoding($false) - $files = get-childitem AxonIvyPortal/*/pom.xml,Showcase/*/pom.xml,AxonIvyPortal/PortalTest/customized_pom.xml,AxonIvyPortal/portal-selenium-test/customized_pom.xml,AxonIvyPortal/portal-selenium-test/document_screenshot_pom.xml,Documentation/public-api/pom.xml + $files = get-childitem AxonIvyPortal/*/pom.xml,Showcase/*/pom.xml,AxonIvyPortal/portal-selenium-test/customized_pom.xml,AxonIvyPortal/portal-selenium-test/document_screenshot_pom.xml,Documentation/public-api/pom.xml foreach($file in $files) { $xml = new-object xml $xml.load($file) diff --git a/build/gui-test-cluster/Jenkinsfile b/build/gui-test-cluster/Jenkinsfile deleted file mode 100644 index 38f13222ecc..00000000000 --- a/build/gui-test-cluster/Jenkinsfile +++ /dev/null @@ -1,91 +0,0 @@ -pipeline { - agent {label 'portal-slave'} - - options { - buildDiscarder(logRotator(numToKeepStr: '60', artifactNumToKeepStr: '30')) - } - - tools { - maven '3.9' - jdk '21' - } - - parameters { - string(name: 'engineDownloadURL', defaultValue: '-Divy.engine.download.url=https://developer.axonivy.com/permalink/nightly/axonivy-engine-windows.zip', description: '''Where to download engine? e.g. - -Divy.engine.download.url=https://developer.axonivy.com/permalink/nightly/axonivy-engine-windows.zip for nightly master - -Divy.engine.download.url=https://developer.axonivy.com/permalink/dev/axonivy-engine-windows.zip for dev master - -Divy.engine.download.url=file:///C:/wawa/engine/AxonIvyEngineX.X.X.X_Windows_x64.zip for downloaded engine - -Divy.engine.list.url=https://jenkins.ivyteam.io/job/core_product/job/release%252F9.4/lastSuccessfulBuild/artifact/workspace/ch.ivyteam.ivy.server.product/target/products/ -Divy.engine.os.arch=Windows_x64 for last successful build 9.4 - ''') - } - - environment { - configBackupDir = "c:\\backup\\engine-config" - } - - stages { - stage('build') { - steps { - script { - currentBuild.description = "On ${env.NODE_NAME}" - configs = [node1: [engineDir: "$env.WORKSPACE\\AxonIvyPortal\\PortalTest\\engine1", engineService: "Axon.ivy-master-cluster-gui-test-1", configDir: "master-cluster-node1"], - node2: [engineDir: "$env.WORKSPACE\\AxonIvyPortal\\PortalTest\\engine2", engineService: "Axon.ivy-master-cluster-gui-test-2", configDir: "master-cluster-node2"]] - masterNode = configs['node1'] - masterNodeDir = masterNode['engineDir'] - elasticSearchDataDir = 'C:\\tools\\external-elastic-search\\elasticsearch-master-cluster\\data' - def utils = load 'build\\common\\utils.groovy' - utils.stopAllEngines() - - configs.each{k, v -> - utils.extractEngine(v['engineDir'], params.engineDownloadURL) - } - echo "====================Build Portal modules====================" - def modules = ['AxonIvyPortal/portal-components', 'AxonIvyPortal/portal', 'AxonIvyPortal/PortalKitTestHelper', 'Showcase/portal-user-examples', 'Showcase/portal-developer-examples', 'Showcase/InternalSupport', 'Showcase/portal-components-examples', 'AxonIvyPortal/PortalApp', 'Showcase/portal-demo-app'] - for (module in modules) { - bat "mvn clean install -f ${module}/pom.xml -Divy.engine.directory=${masterNodeDir}" - } - - println powershell(returnStdout: true, script: """ - dropdb --host=10.123.1.30 --username=postgres --no-password ivy-master-cluster-gui-test - rmdir ${elasticSearchDataDir}\\* -recurse - exit 0 - """) - - configs.each{key, config -> - println powershell(returnStdout: true, script: """ - Copy-Item ${configBackupDir}\\${config['configDir']}\\* ${config['engineDir']} -Recurse -Force - exit 0 - """) - } - - bat """ - ${masterNodeDir}\\bin\\EngineConfigCli.exe create-db - ${masterNodeDir}\\bin\\EngineConfigCli.exe config-cluster portal02.server.ivy-cloud.com 8021 - ${configs['node2']['engineDir']}\\bin\\EngineConfigCli.exe config-cluster portal02.server.ivy-cloud.com 8022 - """ - - utils.startWindowsService("ivy-elasticsearch-master-cluster") - utils.startWindowsService(configs['node1']['engineService']) - - echo "====================Deploy Portal modules====================" - println powershell(returnStdout: true, script: """ - \$DEPLOYMENT= "${configs['node1']['engineDir']}\\deploy\\Portal" - Copy-Item Showcase\\portal-demo-app\\target\\*zip -Destination \$DEPLOYMENT - Start-Sleep 6 - Copy-Item Showcase\\portal-developer-examples\\target\\*iar -Destination \$DEPLOYMENT - Start-Sleep 2 - Copy-Item AxonIvyPortal\\PortalKitTestHelper\\target\\*iar -Destination \$DEPLOYMENT - Start-Sleep 2 - Copy-Item Showcase\\InternalSupport\\target\\*iar -Destination \$DEPLOYMENT - """) - - bat """ - mklink /j ${configs['node2']['engineDir']}\\applications ${masterNodeDir}\\applications - """ - utils.startWindowsService(configs['node2']['engineService']) - } - } - } - } - -} diff --git a/build/performance-test/Jenkinsfile b/build/performance-test/Jenkinsfile index d1df8a316cd..0cfc23993ec 100644 --- a/build/performance-test/Jenkinsfile +++ b/build/performance-test/Jenkinsfile @@ -11,7 +11,7 @@ pipeline { environment { engineVersion = 'master' - jmeterSourceDir = 'AxonIvyPortal/PortalTest/jmeter' + jmeterSourceDir = 'AxonIvyPortal/portal-selenium-test/jmeter' ivyDir = '/var/tools/ivy' } diff --git a/build/update-pom/Jenkinsfile b/build/update-pom/Jenkinsfile index 3c637a6da5d..0868233a77f 100644 --- a/build/update-pom/Jenkinsfile +++ b/build/update-pom/Jenkinsfile @@ -62,7 +62,7 @@ pipeline { def updateVersion() { def pomFiles = ['AxonIvyPortal/portal-components/pom.xml', 'AxonIvyPortal/portal/pom.xml', 'AxonIvyPortal/portal-migration/pom.xml', 'AxonIvyPortal/portal-selenium-test/pom.xml', 'AxonIvyPortal/portal-selenium-test/customized_pom.xml', 'AxonIvyPortal/portal-selenium-test/document_screenshot_pom.xml', - 'AxonIvyPortal/PortalTest/customized_pom.xml', 'AxonIvyPortal/PortalTest/pom.xml', 'AxonIvyPortal/PortalKitTestHelper/pom.xml', 'Showcase/portal-user-examples/pom.xml', + 'AxonIvyPortal/PortalKitTestHelper/pom.xml', 'Showcase/portal-user-examples/pom.xml', 'Showcase/portal-developer-examples/pom.xml', 'Showcase/InternalSupport/pom.xml', 'Showcase/portal-components-examples/pom.xml'] for (pomFile in pomFiles) { maven cmd: "-f ${pomFile} versions:set-property versions:commit -Dproperty=ivy.engine.version -DnewVersion=${params.ivyEngineVersion}" From ce533639ebd8981b784564efe66ca3cfd99d3047 Mon Sep 17 00:00:00 2001 From: tphvu-axonivy Date: Wed, 2 Oct 2024 16:43:51 +0700 Subject: [PATCH 2/2] IVYPORTAL-17700-Remove-portalTest_VERSION_LE - remove in gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1be8a2d85b8..da2700717cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ AxonIvyPortal/AxonIvyExpress/src_dataClasses/ AxonIvyPortal/PortalKitTestHelper/src_dataClasses/ Showcase/InternalSupport/src_dataClasses/ -AxonIvyPortal/PortalTest/src_dataClasses/ Showcase/InternalSupport/target/ **/.flattened-pom.xml \ No newline at end of file