diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7ac61cc..5767cac 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -111,7 +111,11 @@ jobs: - name: Core Image run: GOPROXY=direct IMG_TOOL=docker make build-image - name: Run e2e + env: + GITEE_TOKEN: ${{ secrets.GITEE_TOKEN }} run: | + sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose + sudo chmod u+x /usr/local/bin/docker-compose make test-e2e - name: Operator Image run: cd operator && make docker-build @@ -136,4 +140,4 @@ jobs: sudo atest service install sudo atest service restart - name: Test - run: make test-ui test-e2e + run: make test-ui diff --git a/.gitpod.yml b/.gitpod.yml index e032143..7d5ab43 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,3 +1,8 @@ +# See https://www.gitpod.io/docs/configure/workspaces tasks: - - init: make build - command: docker run --pull always --network host ghcr.io/linuxsuren/api-testing:master + - init: make init-env + before: IMG_TOOL=docker GOPROXY= make build-ext copy-ext build-image + command: cd console/atest-ui/ && npm i + +ports: + - port: 5713 # console interactive port diff --git a/Makefile b/Makefile index 9a85e1b..35edd0b 100644 --- a/Makefile +++ b/Makefile @@ -6,21 +6,27 @@ HELM_VERSION?=v0.0.2 APP_VERSION?=v0.0.13 HELM_REPO?=docker.io/linuxsuren +fmt: + go fmt ./... + cd extensions/store-etcd && go fmt ./... + cd extensions/store-git && go fmt ./... + cd extensions/store-orm && go fmt ./... + cd extensions/store-s3 && go fmt ./... build: mkdir -p bin rm -rf bin/atest go build ${TOOLEXEC} -a -o bin/atest main.go -build-ext: build-ext-git build-ext-orm build-ext-s3 +build-ext: build-ext-git build-ext-orm build-ext-s3 build-ext-etcd build-ext-git: CGO_ENABLED=0 go build -ldflags "-w -s" -o bin/atest-store-git extensions/store-git/main.go build-ext-orm: CGO_ENABLED=0 go build -ldflags "-w -s" -o bin/atest-store-orm extensions/store-orm/main.go build-ext-etcd: CGO_ENABLED=0 go build -ldflags "-w -s" -o bin/atest-store-etcd extensions/store-etcd/main.go -build-ui: - cd console/atest-ui && npm i && npm run build-only build-ext-s3: CGO_ENABLED=0 go build -ldflags "-w -s" -o bin/atest-store-s3 extensions/store-s3/main.go +build-ui: + cd console/atest-ui && npm i && npm run build-only embed-ui: cd console/atest-ui && npm i && npm run build-only cp console/atest-ui/dist/index.html cmd/data/index.html @@ -98,7 +104,7 @@ test-operator: test-all-backend: test test-collector test-store-orm test-store-s3 test-store-git test-store-etcd test-all: test-all-backend test-ui test-e2e: - cd extensions/e2e && docker-compose build && docker-compose up && docker-compose down + cd extensions/e2e && ./start.sh install-precheck: cp .github/pre-commit .git/hooks/pre-commit @@ -151,3 +157,7 @@ install-tool: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 hd i protoc-gen-grpc-web hd i protoc-gen-grpc-gateway +init-env: + curl https://linuxsuren.github.io/tools/install.sh|bash + hd i cli/cli + gh extension install linuxsuren/gh-dev diff --git a/console/atest-ui/package-lock.json b/console/atest-ui/package-lock.json index e82649a..795f87f 100644 --- a/console/atest-ui/package-lock.json +++ b/console/atest-ui/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "element-plus": "^2.3.7", "intro.js": "^7.0.1", + "jsonpath-plus": "^7.2.0", "skywalking-client-js": "^0.10.0", "vue": "^3.3.4", "vue-i18n": "^9.2.2", @@ -8747,6 +8748,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/jsprim": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", @@ -18936,6 +18945,11 @@ "universalify": "^2.0.0" } }, + "jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==" + }, "jsprim": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", diff --git a/console/atest-ui/package.json b/console/atest-ui/package.json index ea4c157..431bc37 100644 --- a/console/atest-ui/package.json +++ b/console/atest-ui/package.json @@ -18,6 +18,7 @@ "dependencies": { "element-plus": "^2.3.7", "intro.js": "^7.0.1", + "jsonpath-plus": "^7.2.0", "skywalking-client-js": "^0.10.0", "vue": "^3.3.4", "vue-i18n": "^9.2.2", diff --git a/console/atest-ui/src/App.vue b/console/atest-ui/src/App.vue index b0f5a08..549e389 100644 --- a/console/atest-ui/src/App.vue +++ b/console/atest-ui/src/App.vue @@ -10,7 +10,7 @@ import { ElTree, ElMessage } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus' import { Edit, Share } from '@element-plus/icons-vue' import type { Suite } from './types' -import { GetLastTestCaseLocation, SetLastTestCaseLocation } from './views/cache' +import { Cache } from './views/cache' import { DefaultResponseProcess } from './views/net' import { useI18n } from 'vue-i18n' import ClientMonitor from 'skywalking-client-js' @@ -20,11 +20,12 @@ import setAsDarkTheme from './theme' const { t } = useI18n() -const asDarkMode = ref(false) -function switchAppMode() -{ +const asDarkMode = ref(Cache.GetPreference().darkTheme) +setAsDarkTheme(asDarkMode.value) +watch(asDarkMode, Cache.WatchDarkTheme) +watch(asDarkMode, () => { setAsDarkTheme(asDarkMode.value) -} +}) interface Tree { id: string @@ -38,14 +39,13 @@ interface Tree { const testCaseName = ref('') const testSuite = ref('') -const store = ref('') const testSuiteKind = ref('') const handleNodeClick = (data: Tree) => { if (data.children) { viewName.value = 'testsuite' testSuite.value = data.label - store.value = data.store testSuiteKind.value = data.kind + Cache.SetCurrentStore(data.store) const requestOptions = { method: 'POST', @@ -74,10 +74,10 @@ const handleNodeClick = (data: Tree) => { } }) } else { - SetLastTestCaseLocation(data.parentID, data.id) + Cache.SetLastTestCaseLocation(data.parentID, data.id) testCaseName.value = data.label testSuite.value = data.parent - store.value = data.store + Cache.SetCurrentStore(data.store) testSuiteKind.value = data.kind viewName.value = 'testcase' } @@ -141,15 +141,16 @@ function loadStores() { .then(async (d) => { stores.value = d.data data.value = [] as Tree[] + Cache.SetStores(d.data) for (const item of d.data) { - if (item.ready) { + if (item.ready && !item.disabled) { await loadTestSuites(item.name)() } } if (data.value.length > 0) { - const key = GetLastTestCaseLocation() + const key = Cache.GetLastTestCaseLocation() let targetSuite = {} as Tree let targetChild = {} as Tree @@ -182,7 +183,7 @@ function loadStores() { treeRef.value!.setCurrentKey(targetChild.id) treeRef.value!.setCheckedKeys([targetChild.id], false) testSuite.value = targetSuite.label - store.value = targetSuite.store + Cache.SetCurrentStore(targetSuite.store ) testSuiteKind.value = targetChild.kind } else { viewName.value = "" @@ -311,7 +312,7 @@ watch(viewName, (val) => { customTags: [{ key: 'theme', value: asDarkMode.value ? 'dark' : 'light' }, { - key: 'store', value: store.value + key: 'store', value: Cache.GetCurrentStore().name }] }); }) @@ -332,7 +333,7 @@ const suiteKinds = [{ - + @@ -369,7 +370,6 @@ const suiteKinds = [{ /> diff --git a/console/atest-ui/src/locales/en.json b/console/atest-ui/src/locales/en.json index a557c02..5323ce7 100644 --- a/console/atest-ui/src/locales/en.json +++ b/console/atest-ui/src/locales/en.json @@ -38,6 +38,7 @@ "plugin": "Plugin", "pluginName": "Plugin Name", "pluginURL": "Plugin URL", + "disabled": "Disabled", "status": "Status", "operations": "Operations", "storageLocation": "Storage Location", diff --git a/console/atest-ui/src/views/StoreManager.vue b/console/atest-ui/src/views/StoreManager.vue index 1ac0fd3..c9daa91 100644 --- a/console/atest-ui/src/views/StoreManager.vue +++ b/console/atest-ui/src/views/StoreManager.vue @@ -22,7 +22,9 @@ const emptyStore = function() { properties: [{ key: '', value: '' - }] + }], + disabled: false, + readonly: false } as Store } const stores = ref([] as Store[]) @@ -38,6 +40,8 @@ interface Store { username: string password: string ready: boolean + disabled: boolean + readonly: boolean kind: { name: string url: string @@ -86,6 +90,7 @@ function editStore(name: string) { stores.value.forEach((e: Store) => { if (e.name === name) { setStoreForm(e) + return } }) createAction.value = false @@ -97,7 +102,13 @@ function setStoreForm(store: Store) { storeForm.username = store.username storeForm.password = store.password storeForm.kind = store.kind + storeForm.disabled = store.disabled + storeForm.readonly = store.readonly storeForm.properties = store.properties + storeForm.properties.push({ + key: '', + value: '' + }) } function addStore() { @@ -107,7 +118,9 @@ function addStore() { } const rules = reactive>({ - name: [{ required: true, message: 'Name is required', trigger: 'blur' }] + name: [{ required: true, message: 'Name is required', trigger: 'blur' }], + url: [{ required: true, message: 'URL is required', trigger: 'blur' }], + "kind.name": [{ required: true, message: 'Plugin is required', trigger: 'blur' }] }) const submitForm = async (formEl: FormInstance | undefined) => { if (!formEl) return @@ -166,7 +179,7 @@ function storeVerify(formEl: FormInstance | undefined) { } }) .then((e) => { - if (e.success) { + if (e.ready) { ElMessage({ message: 'Verified!', type: 'success' @@ -284,6 +297,9 @@ function updateKeys() { + + + diff --git a/console/atest-ui/src/views/TestCase.vue b/console/atest-ui/src/views/TestCase.vue index 39af073..99d2fa8 100644 --- a/console/atest-ui/src/views/TestCase.vue +++ b/console/atest-ui/src/views/TestCase.vue @@ -1,26 +1,29 @@