angular-uitest 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +336 -0
  3. package/bin/samaro-allure.mjs +178 -0
  4. package/bin/samaro-init.mjs +407 -0
  5. package/bin/samaro-test.mjs +119 -0
  6. package/dist/cjs/config/index.d.ts +4 -0
  7. package/dist/cjs/config/index.d.ts.map +1 -0
  8. package/dist/cjs/config/index.js +11 -0
  9. package/dist/cjs/config/index.js.map +1 -0
  10. package/dist/cjs/config/playwright.component.config.d.ts +12 -0
  11. package/dist/cjs/config/playwright.component.config.d.ts.map +1 -0
  12. package/dist/cjs/config/playwright.component.config.js +42 -0
  13. package/dist/cjs/config/playwright.component.config.js.map +1 -0
  14. package/dist/cjs/config/playwright.config.d.ts +14 -0
  15. package/dist/cjs/config/playwright.config.d.ts.map +1 -0
  16. package/dist/cjs/config/playwright.config.js +53 -0
  17. package/dist/cjs/config/playwright.config.js.map +1 -0
  18. package/dist/cjs/config/vitest.config.d.ts +12 -0
  19. package/dist/cjs/config/vitest.config.d.ts.map +1 -0
  20. package/dist/cjs/config/vitest.config.js +60 -0
  21. package/dist/cjs/config/vitest.config.js.map +1 -0
  22. package/dist/cjs/helpers/allure.d.ts +141 -0
  23. package/dist/cjs/helpers/allure.d.ts.map +1 -0
  24. package/dist/cjs/helpers/allure.js +331 -0
  25. package/dist/cjs/helpers/allure.js.map +1 -0
  26. package/dist/cjs/helpers/api.d.ts +69 -0
  27. package/dist/cjs/helpers/api.d.ts.map +1 -0
  28. package/dist/cjs/helpers/api.js +163 -0
  29. package/dist/cjs/helpers/api.js.map +1 -0
  30. package/dist/cjs/helpers/auth.d.ts +35 -0
  31. package/dist/cjs/helpers/auth.d.ts.map +1 -0
  32. package/dist/cjs/helpers/auth.js +104 -0
  33. package/dist/cjs/helpers/auth.js.map +1 -0
  34. package/dist/cjs/helpers/config.d.ts +34 -0
  35. package/dist/cjs/helpers/config.d.ts.map +1 -0
  36. package/dist/cjs/helpers/config.js +70 -0
  37. package/dist/cjs/helpers/config.js.map +1 -0
  38. package/dist/cjs/helpers/debug.d.ts +48 -0
  39. package/dist/cjs/helpers/debug.d.ts.map +1 -0
  40. package/dist/cjs/helpers/debug.js +86 -0
  41. package/dist/cjs/helpers/debug.js.map +1 -0
  42. package/dist/cjs/helpers/index.d.ts +8 -0
  43. package/dist/cjs/helpers/index.d.ts.map +1 -0
  44. package/dist/cjs/helpers/index.js +76 -0
  45. package/dist/cjs/helpers/index.js.map +1 -0
  46. package/dist/cjs/helpers/setup.d.ts +50 -0
  47. package/dist/cjs/helpers/setup.d.ts.map +1 -0
  48. package/dist/cjs/helpers/setup.js +137 -0
  49. package/dist/cjs/helpers/setup.js.map +1 -0
  50. package/dist/cjs/src/index.d.ts +17 -0
  51. package/dist/cjs/src/index.d.ts.map +1 -0
  52. package/dist/cjs/src/index.js +99 -0
  53. package/dist/cjs/src/index.js.map +1 -0
  54. package/dist/esm/config/index.d.ts +4 -0
  55. package/dist/esm/config/index.d.ts.map +1 -0
  56. package/dist/esm/config/index.mjs +4 -0
  57. package/dist/esm/config/index.mjs.map +1 -0
  58. package/dist/esm/config/playwright.component.config.d.ts +12 -0
  59. package/dist/esm/config/playwright.component.config.d.ts.map +1 -0
  60. package/dist/esm/config/playwright.component.config.mjs +39 -0
  61. package/dist/esm/config/playwright.component.config.mjs.map +1 -0
  62. package/dist/esm/config/playwright.config.d.ts +14 -0
  63. package/dist/esm/config/playwright.config.d.ts.map +1 -0
  64. package/dist/esm/config/playwright.config.mjs +50 -0
  65. package/dist/esm/config/playwright.config.mjs.map +1 -0
  66. package/dist/esm/config/vitest.config.d.ts +12 -0
  67. package/dist/esm/config/vitest.config.d.ts.map +1 -0
  68. package/dist/esm/config/vitest.config.mjs +56 -0
  69. package/dist/esm/config/vitest.config.mjs.map +1 -0
  70. package/dist/esm/helpers/allure.d.ts +141 -0
  71. package/dist/esm/helpers/allure.d.ts.map +1 -0
  72. package/dist/esm/helpers/allure.mjs +306 -0
  73. package/dist/esm/helpers/allure.mjs.map +1 -0
  74. package/dist/esm/helpers/api.d.ts +69 -0
  75. package/dist/esm/helpers/api.d.ts.map +1 -0
  76. package/dist/esm/helpers/api.mjs +154 -0
  77. package/dist/esm/helpers/api.mjs.map +1 -0
  78. package/dist/esm/helpers/auth.d.ts +35 -0
  79. package/dist/esm/helpers/auth.d.ts.map +1 -0
  80. package/dist/esm/helpers/auth.mjs +96 -0
  81. package/dist/esm/helpers/auth.mjs.map +1 -0
  82. package/dist/esm/helpers/config.d.ts +34 -0
  83. package/dist/esm/helpers/config.d.ts.map +1 -0
  84. package/dist/esm/helpers/config.mjs +63 -0
  85. package/dist/esm/helpers/config.mjs.map +1 -0
  86. package/dist/esm/helpers/debug.d.ts +48 -0
  87. package/dist/esm/helpers/debug.d.ts.map +1 -0
  88. package/dist/esm/helpers/debug.mjs +76 -0
  89. package/dist/esm/helpers/debug.mjs.map +1 -0
  90. package/dist/esm/helpers/index.d.ts +8 -0
  91. package/dist/esm/helpers/index.d.ts.map +1 -0
  92. package/dist/esm/helpers/index.mjs +19 -0
  93. package/dist/esm/helpers/index.mjs.map +1 -0
  94. package/dist/esm/helpers/setup.d.ts +50 -0
  95. package/dist/esm/helpers/setup.d.ts.map +1 -0
  96. package/dist/esm/helpers/setup.mjs +95 -0
  97. package/dist/esm/helpers/setup.mjs.map +1 -0
  98. package/dist/esm/src/index.d.ts +17 -0
  99. package/dist/esm/src/index.d.ts.map +1 -0
  100. package/dist/esm/src/index.mjs +40 -0
  101. package/dist/esm/src/index.mjs.map +1 -0
  102. package/dist/types/config/index.d.ts +4 -0
  103. package/dist/types/config/index.d.ts.map +1 -0
  104. package/dist/types/config/playwright.component.config.d.ts +12 -0
  105. package/dist/types/config/playwright.component.config.d.ts.map +1 -0
  106. package/dist/types/config/playwright.config.d.ts +14 -0
  107. package/dist/types/config/playwright.config.d.ts.map +1 -0
  108. package/dist/types/config/vitest.config.d.ts +12 -0
  109. package/dist/types/config/vitest.config.d.ts.map +1 -0
  110. package/dist/types/helpers/allure.d.ts +141 -0
  111. package/dist/types/helpers/allure.d.ts.map +1 -0
  112. package/dist/types/helpers/api.d.ts +69 -0
  113. package/dist/types/helpers/api.d.ts.map +1 -0
  114. package/dist/types/helpers/auth.d.ts +35 -0
  115. package/dist/types/helpers/auth.d.ts.map +1 -0
  116. package/dist/types/helpers/config.d.ts +34 -0
  117. package/dist/types/helpers/config.d.ts.map +1 -0
  118. package/dist/types/helpers/debug.d.ts +48 -0
  119. package/dist/types/helpers/debug.d.ts.map +1 -0
  120. package/dist/types/helpers/index.d.ts +8 -0
  121. package/dist/types/helpers/index.d.ts.map +1 -0
  122. package/dist/types/helpers/setup.d.ts +50 -0
  123. package/dist/types/helpers/setup.d.ts.map +1 -0
  124. package/dist/types/src/index.d.ts +17 -0
  125. package/dist/types/src/index.d.ts.map +1 -0
  126. package/package.json +140 -0
  127. package/schematics/collection.json +11 -0
  128. package/schematics/ng-add/index.js +126 -0
  129. package/schematics/ng-add/schema.json +26 -0
  130. package/scripts/check-allure-results.mjs +300 -0
  131. package/scripts/rename-esm-files.mjs +76 -0
  132. package/types/allure.d.ts +76 -0
  133. package/types/global.d.ts +49 -0
@@ -0,0 +1,50 @@
1
+ import { Browser, BrowserContext, Page, APIRequestContext } from '@playwright/test';
2
+ import { APIUser } from './api.js';
3
+ export interface TestUser extends APIUser {
4
+ token?: string;
5
+ }
6
+ export interface IsolatedUserContext {
7
+ context: BrowserContext;
8
+ page: Page;
9
+ user: TestUser;
10
+ }
11
+ /**
12
+ * Create a user in an isolated browser context
13
+ * This provides full isolation for tests
14
+ */
15
+ export declare function createUserInIsolation(browser: Browser, user?: Partial<TestUser>): Promise<IsolatedUserContext>;
16
+ /**
17
+ * Create a user via API (faster, no browser context needed)
18
+ */
19
+ export declare function createUserViaAPI(request: APIRequestContext, user?: Partial<TestUser>): Promise<TestUser & {
20
+ token: string;
21
+ }>;
22
+ /**
23
+ * Setup authenticated page with token
24
+ */
25
+ export declare function setupAuthenticatedPage(page: Page, token: string): Promise<void>;
26
+ /**
27
+ * Create multiple articles via API
28
+ */
29
+ export declare function createManyArticles(request: APIRequestContext, token: string, count: number, baseTitle?: string): Promise<Array<{
30
+ slug: string;
31
+ title: string;
32
+ }>>;
33
+ /**
34
+ * Cleanup helper for test data
35
+ */
36
+ export declare function cleanupTestData(request: APIRequestContext, token: string, articles: Array<{
37
+ slug: string;
38
+ }>): Promise<void>;
39
+ /**
40
+ * Wait for Angular to be stable
41
+ */
42
+ export declare function waitForAngular(page: Page): Promise<void>;
43
+ /**
44
+ * Safe navigation with retry
45
+ */
46
+ export declare function safeGoto(page: Page, url: string, options?: {
47
+ timeout?: number;
48
+ retries?: number;
49
+ }): Promise<void>;
50
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../helpers/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEpF,OAAO,EAAsB,OAAO,EAAE,MAAM,UAAU,CAAC;AAEvD,MAAM,WAAW,QAAS,SAAQ,OAAO;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAa9B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GACvB,OAAO,CAAC,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CASvC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAuB,GACjC,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAejD;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9D;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACnD,OAAO,CAAC,IAAI,CAAC,CAYf"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * SamaroUItest - Comprehensive Testing Framework for Angular
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import 'reflect-metadata';
7
+ export { createVitestConfig, createPlaywrightConfig, createComponentConfig, mergeConfig, type SamaroVitestOptions, type SamaroPlaywrightOptions, type SamaroComponentOptions, } from '../config/index.js';
8
+ export { setDebugInterfaceName, getDebugInterfaceName, getToken, getAuthState, getCurrentUser, waitForAuthState, isDebugInterfaceAvailable, getDebugData, type AuthState, type User, register, login, logout, generateUniqueUser, isLoggedIn, getCurrentUsername, type UserCredentials, type AuthResult, getAPIConfig, registerUserViaAPI, loginUserViaAPI, createArticleViaAPI, deleteArticleViaAPI, updateUserViaAPI, getCurrentUserViaAPI, type APIConfig, type APIUser, type APIAuthResponse, createUserInIsolation, createUserViaAPI, setupAuthenticatedPage, createManyArticles, cleanupTestData, waitForAngular, safeGoto, type TestUser, type IsolatedUserContext, getConfig, isCI, isDebug, getBrowserLaunchOptions, setTestEnv, type SamaroConfig, severity, tag, epic, feature, story, owner, description, descriptionHtml, link, issue, tms, allure, allureMeta, addLabel, addLink, addAttachment, attachScreenshot, attachJson, attachText, attachHtml, allureStep, getAllureMetadata, getAllureMetadataKeys, type Severity, type LinkType, type LabelName, type AllureMetadataOptions, type Label, type Link, type Parameter, type Attachment, type Status, type StatusDetails, type StepResult, type TestResult, type TestResultContainer, } from '../helpers/index.js';
9
+ /**
10
+ * Version of SamaroUItest
11
+ */
12
+ export declare const VERSION = "1.0.2";
13
+ /**
14
+ * Check if the package is properly installed
15
+ */
16
+ export declare function checkInstallation(): boolean;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,kBAAkB,CAAC;AAG1B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAEL,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,IAAI,EAGT,QAAQ,EACR,KAAK,EACL,MAAM,EACN,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,EAGf,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,eAAe,EAGpB,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAGxB,SAAS,EACT,IAAI,EACJ,OAAO,EACP,uBAAuB,EACvB,UAAU,EACV,KAAK,YAAY,EAGjB,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,OAAO,EACP,KAAK,EACL,KAAK,EACL,WAAW,EACX,eAAe,EACf,IAAI,EACJ,KAAK,EACL,GAAG,EACH,MAAM,EACN,UAAU,EACV,QAAQ,EACR,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C"}
package/package.json ADDED
@@ -0,0 +1,140 @@
1
+ {
2
+ "name": "angular-uitest",
3
+ "version": "1.0.3",
4
+ "description": "Comprehensive testing framework for Angular with Vitest, Playwright, and Allure reporting",
5
+ "main": "./dist/cjs/src/index.js",
6
+ "module": "./dist/esm/src/index.mjs",
7
+ "types": "./dist/types/src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/types/src/index.d.ts",
12
+ "default": "./dist/esm/src/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/types/src/index.d.ts",
16
+ "default": "./dist/cjs/src/index.js"
17
+ }
18
+ },
19
+ "./config": {
20
+ "import": {
21
+ "types": "./dist/types/config/index.d.ts",
22
+ "default": "./dist/esm/config/index.mjs"
23
+ },
24
+ "require": {
25
+ "types": "./dist/types/config/index.d.ts",
26
+ "default": "./dist/cjs/config/index.js"
27
+ }
28
+ },
29
+ "./helpers": {
30
+ "import": {
31
+ "types": "./dist/types/helpers/index.d.ts",
32
+ "default": "./dist/esm/helpers/index.mjs"
33
+ },
34
+ "require": {
35
+ "types": "./dist/types/helpers/index.d.ts",
36
+ "default": "./dist/cjs/helpers/index.js"
37
+ }
38
+ },
39
+ "./allure": {
40
+ "import": {
41
+ "types": "./dist/types/helpers/allure.d.ts",
42
+ "default": "./dist/esm/helpers/allure.mjs"
43
+ },
44
+ "require": {
45
+ "types": "./dist/types/helpers/allure.d.ts",
46
+ "default": "./dist/cjs/helpers/allure.js"
47
+ }
48
+ },
49
+ "./package.json": "./package.json"
50
+ },
51
+ "bin": {
52
+ "samaro": "bin/samaro-init.mjs",
53
+ "samaro-init": "bin/samaro-init.mjs",
54
+ "samaro-test": "bin/samaro-test.mjs",
55
+ "samaro-allure": "bin/samaro-allure.mjs"
56
+ },
57
+ "files": [
58
+ "dist/**/*",
59
+ "bin/**/*",
60
+ "scripts/**/*",
61
+ "types/**/*",
62
+ "schematics/**/*",
63
+ "README.md",
64
+ "LICENSE"
65
+ ],
66
+ "scripts": {
67
+ "build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types && npm run rename:esm",
68
+ "build:esm": "tsc -p tsconfig.esm.json",
69
+ "build:cjs": "tsc -p tsconfig.cjs.json",
70
+ "build:types": "tsc -p tsconfig.types.json",
71
+ "rename:esm": "node scripts/rename-esm-files.mjs",
72
+ "clean": "rimraf dist",
73
+ "prepublishOnly": "npm run build",
74
+ "test": "vitest",
75
+ "format": "prettier --write ."
76
+ },
77
+ "keywords": [
78
+ "angular",
79
+ "testing",
80
+ "vitest",
81
+ "playwright",
82
+ "allure",
83
+ "e2e",
84
+ "component-testing",
85
+ "test-framework",
86
+ "automation"
87
+ ],
88
+ "author": "Samaro",
89
+ "license": "MIT",
90
+ "repository": {
91
+ "type": "git",
92
+ "url": "git+https://github.com/angular-uitest/angular-uitest.git"
93
+ },
94
+ "bugs": {
95
+ "url": "https://github.com/angular-uitest/angular-uitest/issues"
96
+ },
97
+ "homepage": "https://github.com/angular-uitest/angular-uitest#readme",
98
+ "engines": {
99
+ "node": ">=18.0.0",
100
+ "npm": ">=8.0.0"
101
+ },
102
+ "peerDependencies": {
103
+ "@angular/core": ">=15.0.0",
104
+ "@angular/platform-browser-dynamic": ">=15.0.0",
105
+ "typescript": ">=4.8.0"
106
+ },
107
+ "dependencies": {
108
+ "@analogjs/vite-plugin-angular": "^2.2.2",
109
+ "reflect-metadata": "^0.2.2",
110
+ "@playwright/test": "^1.58.0",
111
+ "@vitest/coverage-v8": "^4.1.9",
112
+ "@vitest/ui": "^4.0.18",
113
+ "allure": "^3.14.2",
114
+ "allure-commandline": "^2.43.0",
115
+ "allure-js-commons": "^3.10.2",
116
+ "allure-playwright": "^3.10.2",
117
+ "allure-vitest": "^3.10.2",
118
+ "jsdom": "^27.4.0",
119
+ "playwright": "^1.58.0",
120
+ "vitest": "^4.0.18",
121
+ "zone.js": "^0.16.0",
122
+ "cross-spawn": "^7.0.3",
123
+ "chalk": "^4.1.2",
124
+ "inquirer": "^8.2.6"
125
+ },
126
+ "devDependencies": {
127
+ "@angular-devkit/schematics": "^17.0.0",
128
+ "@types/cross-spawn": "^6.0.6",
129
+ "@types/inquirer": "^9.0.7",
130
+ "@types/node": "^20.0.0",
131
+ "cpy-cli": "^5.0.0",
132
+ "prettier": "^3.0.0",
133
+ "rimraf": "^5.0.5",
134
+ "typescript": "^5.3.0"
135
+ },
136
+ "schematics": "./schematics/collection.json",
137
+ "ng-add": {
138
+ "save": "devDependencies"
139
+ }
140
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "@angular-devkit/schematics/collection-schema.json",
3
+ "schematics": {
4
+ "ng-add": {
5
+ "description": "Add SamaroUItest to the project",
6
+ "factory": "./ng-add/index#ngAdd",
7
+ "schema": "./ng-add/schema.json",
8
+ "aliases": ["install", "setup"]
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,126 @@
1
+ import { chain, schematic } from '@angular-devkit/schematics';
2
+ import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
3
+
4
+ function ngAdd(options) {
5
+ return (tree, context) => {
6
+ context.addTask(new NodePackageInstallTask());
7
+
8
+ context.logger.info('๐Ÿš€ Installing AngularUITest...');
9
+
10
+ return chain([
11
+ updatePackageJson(),
12
+ createConfigFiles(options),
13
+ createDirectories(),
14
+ ])(tree, context);
15
+ };
16
+ }
17
+
18
+ function updatePackageJson() {
19
+ return (tree, context) => {
20
+ const packageJsonPath = '/package.json';
21
+ const packageJsonBuffer = tree.read(packageJsonPath);
22
+
23
+ if (!packageJsonBuffer) {
24
+ throw new Error('Could not read package.json');
25
+ }
26
+
27
+ const packageJson = JSON.parse(packageJsonBuffer.toString());
28
+
29
+ packageJson.scripts = {
30
+ ...packageJson.scripts,
31
+ 'test': 'samaro-test vitest',
32
+ 'test:run': 'samaro-test "vitest --run"',
33
+ 'test:ui': 'samaro-test "vitest --ui"',
34
+ 'test:coverage': 'samaro-test "vitest --coverage"',
35
+ 'test:e2e': 'samaro-test "playwright test"',
36
+ 'test:e2e:ui': 'samaro-test "playwright test --ui"',
37
+ 'test:e2e:headed': 'samaro-test "playwright test --headed"',
38
+ 'test:e2e:debug': 'samaro-test "playwright test --debug"',
39
+ 'test:ct': 'samaro-test "playwright test --config playwright.component.config.ts"',
40
+ 'test:ct:ui': 'samaro-test "playwright test --config playwright.component.config.ts --ui"',
41
+ 'allure:generate': 'samaro-allure generate',
42
+ 'allure:open': 'samaro-allure open',
43
+ 'allure:clean': 'samaro-allure clean',
44
+ };
45
+
46
+ tree.overwrite(packageJsonPath, JSON.stringify(packageJson, null, 2));
47
+ context.logger.info('โœ… Updated package.json scripts');
48
+
49
+ return tree;
50
+ };
51
+ }
52
+
53
+ function createConfigFiles(options) {
54
+ return (tree, context) => {
55
+ // Create vitest.config.ts
56
+ tree.create('/vitest.config.ts', `import { createVitestConfig } from 'angular-uitest/config';
57
+ import { fileURLToPath } from 'url';
58
+ import { dirname } from 'path';
59
+
60
+ const __filename = fileURLToPath(import.meta.url);
61
+ const __dirname = dirname(__filename);
62
+
63
+ export default createVitestConfig({
64
+ projectRoot: __dirname,
65
+ testGlob: 'src/**/*.spec.ts',
66
+ resultsDir: 'allure-unit-results',
67
+ });
68
+ `);
69
+ context.logger.info('โœ… Created vitest.config.ts');
70
+
71
+ // Create playwright.config.ts
72
+ tree.create('/playwright.config.ts', `import { createPlaywrightConfig } from 'angular-uitest/config';
73
+
74
+ export default createPlaywrightConfig({
75
+ baseURL: 'http://localhost:4200',
76
+ testDir: './e2e',
77
+ resultsDir: 'allure-e2e-results',
78
+ webServerCommand: 'npm run start',
79
+ webServerPort: 4200,
80
+ });
81
+ `);
82
+ context.logger.info('โœ… Created playwright.config.ts');
83
+
84
+ // Create playwright.component.config.ts
85
+ tree.create('/playwright.component.config.ts', `import { createComponentConfig } from 'angular-uitest/config';
86
+
87
+ export default createComponentConfig({
88
+ baseURL: 'http://localhost:4200',
89
+ testDir: './ct-tests',
90
+ resultsDir: 'allure-ct-results',
91
+ });
92
+ `);
93
+ context.logger.info('โœ… Created playwright.component.config.ts');
94
+
95
+ // Create test-setup.ts in src if it exists
96
+ if (tree.exists('/src')) {
97
+ tree.create('/src/test-setup.ts', `import 'zone.js';
98
+ import 'zone.js/testing';
99
+ import { getTestBed } from '@angular/core/testing';
100
+ import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
101
+
102
+ getTestBed().initTestEnvironment(
103
+ BrowserDynamicTestingModule,
104
+ platformBrowserDynamicTesting()
105
+ );
106
+ `);
107
+ context.logger.info('โœ… Created src/test-setup.ts');
108
+ }
109
+
110
+ return tree;
111
+ };
112
+ }
113
+
114
+ function createDirectories() {
115
+ return (tree, context) => {
116
+ tree.create('/e2e/.gitkeep', '');
117
+ tree.create('/e2e/helpers/.gitkeep', '');
118
+ tree.create('/ct-tests/.gitkeep', '');
119
+
120
+ context.logger.info('โœ… Created test directories');
121
+
122
+ return tree;
123
+ };
124
+ }
125
+
126
+ export { ngAdd };
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "SamaroUItestNgAddSchema",
4
+ "title": "SamaroUItest ng-add Options Schema",
5
+ "type": "object",
6
+ "properties": {
7
+ "project": {
8
+ "type": "string",
9
+ "description": "The name of the project to add SamaroUItest to",
10
+ "$default": {
11
+ "$source": "projectName"
12
+ }
13
+ },
14
+ "skipInstall": {
15
+ "type": "boolean",
16
+ "default": false,
17
+ "description": "Skip installing dependencies"
18
+ },
19
+ "includeSampleTests": {
20
+ "type": "boolean",
21
+ "default": true,
22
+ "description": "Include sample test files"
23
+ }
24
+ },
25
+ "required": []
26
+ }
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Pre-test Allure results checker
5
+ *
6
+ * This script checks for existing Allure result data and prompts the user
7
+ * to either clean it, keep it, or cancel the test run.
8
+ */
9
+
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import { spawn } from 'child_process';
13
+ import readline from 'readline';
14
+
15
+ /**
16
+ * Detect if running in a CI environment
17
+ * Checks for common CI environment variables
18
+ */
19
+ function isCIEnvironment() {
20
+ const ciEnvVars = [
21
+ 'CI',
22
+ 'CONTINUOUS_INTEGRATION',
23
+ 'BUILD_NUMBER',
24
+ 'BUILD_ID',
25
+ 'TEAMCITY_VERSION',
26
+ 'TRAVIS',
27
+ 'CIRCLECI',
28
+ 'GITHUB_ACTIONS',
29
+ 'GITLAB_CI',
30
+ 'JENKINS_URL',
31
+ 'JENKINS_HOME',
32
+ 'HUDSON_URL',
33
+ 'DRONE',
34
+ 'APPVEYOR',
35
+ 'CODEBUILD_BUILD_ID',
36
+ 'TF_BUILD',
37
+ 'BITBUCKET_PIPELINE_UUID',
38
+ 'BAMBOO_PLAN_KEY',
39
+ 'GOCD_SERVER_URL',
40
+ ];
41
+
42
+ return ciEnvVars.some((envVar) => process.env[envVar]) || process.env.SAMARO_AUTO_CLEAN;
43
+ }
44
+
45
+ const rl = readline.createInterface({
46
+ input: process.stdin,
47
+ output: process.stdout,
48
+ });
49
+
50
+ // Allure result directories to check
51
+ const ALLURE_DIRS = [
52
+ { name: 'Unit Tests', dir: 'allure-unit-results', type: 'unit' },
53
+ { name: 'E2E Tests', dir: 'allure-e2e-results', type: 'e2e' },
54
+ { name: 'Component Tests', dir: 'allure-ct-results', type: 'ct' },
55
+ ];
56
+
57
+ // Colors for terminal output
58
+ const colors = {
59
+ reset: '\x1b[0m',
60
+ bright: '\x1b[1m',
61
+ red: '\x1b[31m',
62
+ green: '\x1b[32m',
63
+ yellow: '\x1b[33m',
64
+ blue: '\x1b[34m',
65
+ cyan: '\x1b[36m',
66
+ gray: '\x1b[90m',
67
+ };
68
+
69
+ /**
70
+ * Check if a directory exists and get its contents
71
+ */
72
+ function checkDirectory(dirPath) {
73
+ const fullPath = path.join(process.cwd(), dirPath);
74
+
75
+ if (!fs.existsSync(fullPath)) {
76
+ return { exists: false, count: 0, lastModified: null };
77
+ }
78
+
79
+ try {
80
+ const files = fs.readdirSync(fullPath);
81
+ const stats = fs.statSync(fullPath);
82
+
83
+ return {
84
+ exists: true,
85
+ count: files.length,
86
+ lastModified: stats.mtime,
87
+ };
88
+ } catch (error) {
89
+ return { exists: false, count: 0, lastModified: null, error: error.message };
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Format the last modified time
95
+ */
96
+ function formatTime(date) {
97
+ if (!date) return '-';
98
+
99
+ const now = new Date();
100
+ const diff = now - date;
101
+ const minutes = Math.floor(diff / 60000);
102
+ const hours = Math.floor(diff / 3600000);
103
+ const days = Math.floor(diff / 86400000);
104
+
105
+ if (minutes < 1) return 'Just now';
106
+ if (minutes < 60) return `${minutes} min ago`;
107
+ if (hours < 24) return `${hours} hour${hours > 1 ? 's' : ''} ago`;
108
+ return `${days} day${days > 1 ? 's' : ''} ago`;
109
+ }
110
+
111
+ /**
112
+ * Clean all Allure result directories
113
+ */
114
+ function cleanAllureResults() {
115
+ console.log(`${colors.cyan}๐Ÿงน Cleaning Allure results...${colors.reset}\n`);
116
+
117
+ let cleanedCount = 0;
118
+
119
+ for (const { dir } of ALLURE_DIRS) {
120
+ const fullPath = path.join(process.cwd(), dir);
121
+ if (fs.existsSync(fullPath)) {
122
+ try {
123
+ fs.rmSync(fullPath, { recursive: true, force: true });
124
+ console.log(` ${colors.green}โœ“${colors.reset} Removed ${dir}/`);
125
+ cleanedCount++;
126
+ } catch (error) {
127
+ console.log(` ${colors.red}โœ—${colors.reset} Failed to remove ${dir}/: ${error.message}`);
128
+ }
129
+ }
130
+ }
131
+
132
+ // Also clean the reports directory
133
+ const reportsPath = path.join(process.cwd(), 'allure-reports');
134
+ if (fs.existsSync(reportsPath)) {
135
+ try {
136
+ fs.rmSync(reportsPath, { recursive: true, force: true });
137
+ console.log(` ${colors.green}โœ“${colors.reset} Removed allure-reports/`);
138
+ cleanedCount++;
139
+ } catch (error) {
140
+ console.log(` ${colors.red}โœ—${colors.reset} Failed to remove allure-reports/: ${error.message}`);
141
+ }
142
+ }
143
+
144
+ console.log(`${colors.green}\nโœ… Cleanup complete!${colors.reset}\n`);
145
+ return cleanedCount;
146
+ }
147
+
148
+ /**
149
+ * Run the actual test command
150
+ */
151
+ function runTestCommand(command) {
152
+ console.log(`${colors.cyan}โ–ถ๏ธ Running: ${command}${colors.reset}\n`);
153
+
154
+ const parts = command.split(' ');
155
+ const cmd = parts[0];
156
+ const args = parts.slice(1);
157
+
158
+ const isWindows = process.platform === 'win32';
159
+
160
+ const child = spawn(cmd, args, {
161
+ stdio: 'inherit',
162
+ shell: isWindows,
163
+ cwd: process.cwd(),
164
+ });
165
+
166
+ child.on('close', (code) => {
167
+ process.exit(code);
168
+ });
169
+
170
+ child.on('error', (error) => {
171
+ console.error(`${colors.red}Failed to run command: ${error.message}${colors.reset}`);
172
+ process.exit(1);
173
+ });
174
+ }
175
+
176
+ /**
177
+ * Show the prompt and handle user input
178
+ */
179
+ function showPrompt(hasExistingResults, testCommand) {
180
+ console.log(`${colors.bright}What would you like to do?${colors.reset}\n`);
181
+
182
+ if (hasExistingResults) {
183
+ console.log(` ${colors.green}[1]${colors.reset} ๐Ÿงน Clean all results and run tests (recommended)`);
184
+ console.log(` ${colors.yellow}[2]${colors.reset} โ–ถ๏ธ Keep results and run tests (will accumulate)`);
185
+ } else {
186
+ console.log(` ${colors.green}[1]${colors.reset} โ–ถ๏ธ Run tests`);
187
+ }
188
+ console.log(` ${colors.red}[3]${colors.reset} โŒ Cancel\n`);
189
+
190
+ const promptText = hasExistingResults
191
+ ? `Select option (1-3): `
192
+ : `Select option (1 or 3): `;
193
+
194
+ rl.question(promptText, (answer) => {
195
+ const choice = answer.trim();
196
+
197
+ if (choice === '1') {
198
+ // Clean and run
199
+ if (hasExistingResults) {
200
+ cleanAllureResults();
201
+ }
202
+ rl.close();
203
+ runTestCommand(testCommand);
204
+ } else if (choice === '2' && hasExistingResults) {
205
+ // Keep results and run
206
+ console.log(`${colors.yellow}\nโš ๏ธ Proceeding with existing results. Reports will show duplicates.${colors.reset}\n`);
207
+ rl.close();
208
+ runTestCommand(testCommand);
209
+ } else if (choice === '3') {
210
+ // Cancel
211
+ console.log(`${colors.gray}\nโŒ Test run cancelled.${colors.reset}`);
212
+ rl.close();
213
+ process.exit(0);
214
+ } else {
215
+ // Invalid input
216
+ console.log(`${colors.red}\nโŒ Invalid option. Please try again.${colors.reset}\n`);
217
+ showPrompt(hasExistingResults, testCommand);
218
+ }
219
+ });
220
+ }
221
+
222
+ /**
223
+ * Auto mode - clean and run without prompting (for CI)
224
+ */
225
+ function autoMode(testCommand) {
226
+ console.log(`${colors.cyan}๐Ÿงน Auto-cleaning Allure results (CI mode)...${colors.reset}\n`);
227
+ cleanAllureResults();
228
+ runTestCommand(testCommand);
229
+ }
230
+
231
+ /**
232
+ * Main function
233
+ */
234
+ function main() {
235
+ // Get the test command from arguments
236
+ const testCommand = process.argv.slice(2).join(' ');
237
+
238
+ if (!testCommand) {
239
+ console.error(`${colors.red}Error: No test command provided${colors.reset}`);
240
+ console.error(`Usage: node check-allure-results.js "<test-command>"`);
241
+ console.error(`Example: node check-allure-results.js "vitest"`);
242
+ process.exit(1);
243
+ }
244
+
245
+ // Check if in CI mode (auto-detect common CI environments)
246
+ if (isCIEnvironment()) {
247
+ console.log(`${colors.cyan}๐Ÿค– CI environment detected - running in auto mode${colors.reset}\n`);
248
+ autoMode(testCommand);
249
+ return;
250
+ }
251
+
252
+ console.log(`\n${colors.bright}๐Ÿ” Checking for existing Allure results...${colors.reset}\n`);
253
+
254
+ // Check all directories
255
+ const results = ALLURE_DIRS.map(({ name, dir }) => ({
256
+ name,
257
+ dir,
258
+ ...checkDirectory(dir),
259
+ }));
260
+
261
+ const hasExistingResults = results.some(r => r.exists && r.count > 0);
262
+
263
+ if (!hasExistingResults) {
264
+ console.log(`${colors.green}โœ… No existing Allure results found.${colors.reset}`);
265
+ console.log(`${colors.gray} Starting with a clean slate.${colors.reset}\n`);
266
+ showPrompt(false, testCommand);
267
+ return;
268
+ }
269
+
270
+ // Show warning
271
+ console.log(`${colors.yellow}โš ๏ธ WARNING: Found existing result data from previous runs:${colors.reset}\n`);
272
+
273
+ // Print table header
274
+ console.log(` ${colors.bright}Directory${colors.reset} Files Last Run`);
275
+ console.log(` ${colors.gray}โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€${colors.reset}`);
276
+
277
+ // Print results
278
+ results.forEach(({ name, dir, exists, count, lastModified }) => {
279
+ if (exists) {
280
+ const namePadded = name.padEnd(28);
281
+ const countPadded = String(count).padStart(5);
282
+ const time = formatTime(lastModified);
283
+ console.log(` ${namePadded} ${countPadded} ${time}`);
284
+ }
285
+ });
286
+
287
+ console.log(`\n${colors.cyan}๐Ÿ’ก Not cleaning will cause duplicate entries in reports.${colors.reset}\n`);
288
+
289
+ showPrompt(true, testCommand);
290
+ }
291
+
292
+ // Handle Ctrl+C gracefully
293
+ rl.on('SIGINT', () => {
294
+ console.log(`\n${colors.gray}\nโŒ Cancelled by user.${colors.reset}`);
295
+ rl.close();
296
+ process.exit(0);
297
+ });
298
+
299
+ // Run the script
300
+ main();