Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8

# 4 space indentation
[*.{py,proto,go,js,ts,json,vue}]
[*.{py,proto,js,ts,json,vue}]
indent_style = space
indent_size = 4

[*.go]
indent_style = tab
9 changes: 9 additions & 0 deletions cmd/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type mockOption struct {
port int
prefix string
metrics bool
tls bool
tlsCert string
tlsKey string
}

func createMockCmd() (c *cobra.Command) {
Expand All @@ -47,12 +50,18 @@ func createMockCmd() (c *cobra.Command) {
flags.IntVarP(&opt.port, "port", "", 6060, "The mock server port")
flags.StringVarP(&opt.prefix, "prefix", "", "/mock", "The mock server API prefix")
flags.BoolVarP(&opt.metrics, "metrics", "m", true, "Enable request metrics collection")
flags.BoolVarP(&opt.tls, "tls", "", false, "Enable TLS mode. Set to true to enable TLS. Alow SAN certificates")
flags.StringVarP(&opt.tlsCert, "cert-file", "", "", "The path to the certificate file, Alow SAN certificates")
flags.StringVarP(&opt.tlsKey, "key-file", "", "", "The path to the key file, Alow SAN certificates")
return
}

func (o *mockOption) runE(c *cobra.Command, args []string) (err error) {
reader := mock.NewLocalFileReader(args[0])
server := mock.NewInMemoryServer(c.Context(), o.port)
if o.tls {
server.WithTLS(o.tlsCert, o.tlsKey)
}
if o.metrics {
server.EnableMetrics()
}
Expand Down
9 changes: 7 additions & 2 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
server.RegisterMockServer(s, mockServerController)
server.RegisterDataServerServer(s, remoteServer.(server.DataServerServer))
server.RegisterThemeExtensionServer(s, remoteServer.(server.ThemeExtensionServer))
server.RegisterUIExtensionServer(s, remoteServer.(server.UIExtensionServer))
serverLogger.Info("gRPC server listening at", "addr", lis.Addr())
s.Serve(lis)
}()
Expand Down Expand Up @@ -345,15 +346,19 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, opts),
server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, opts),
server.RegisterThemeExtensionHandlerFromEndpoint(ctx, mux, gRPCServerAddr, opts),
server.RegisterDataServerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, opts))
server.RegisterDataServerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, opts),
server.RegisterUIExtensionHandlerFromEndpoint(ctx, mux, gRPCServerAddr, opts),
)
} else {
dialOption := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt))}
err = errors.Join(
server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption),
server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption),
server.RegisterThemeExtensionHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption),
server.RegisterDataServerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption))
server.RegisterDataServerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption),
server.RegisterUIExtensionHandlerFromEndpoint(ctx, mux, gRPCServerAddr, dialOption),
)
}

if err == nil {
Expand Down
33 changes: 25 additions & 8 deletions console/atest-ui/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import {
Document,
Menu as IconMenu,
Histogram,
Location,
Expand All @@ -16,10 +15,10 @@ import TestingPanel from './views/TestingPanel.vue'
import TestingHistoryPanel from './views/TestingHistoryPanel.vue'
import MockManager from './views/MockManager.vue'
import StoreManager from './views/StoreManager.vue'
import SecretManager from './views/SecretManager.vue'
import WelcomePage from './views/WelcomePage.vue'
import DataManager from './views/DataManager.vue'
import MagicKey from './components/MagicKey.vue'
import Extension from './views/Extension.vue'
import { useI18n } from 'vue-i18n'
import ElementPlus from 'element-plus';
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
Expand Down Expand Up @@ -109,6 +108,19 @@ const theme = ref(getTheme())
watch(theme, (e) => {
setTheme(e)
})

interface Menu {
name: string
icon: string
index: string
}

const extensionMenus = ref([] as Menu[]);
API.GetMenus((menus) => {
if (menus.data && menus.data.length > 0) {
extensionMenus.value = menus.data;
}
});
</script>

<template>
Expand Down Expand Up @@ -144,14 +156,16 @@ watch(theme, (e) => {
<el-icon><DataAnalysis /></el-icon>
<template #title>{{ t('title.data' )}}</template>
</el-menu-item>
<el-menu-item index="secret">
<el-icon><document /></el-icon>
<template #title>{{ t('title.secrets') }}</template>
</el-menu-item>
<el-menu-item index="store">
<el-icon><location /></el-icon>
<template #title>{{ t('title.stores') }}</template>
</el-menu-item>
<span v-for="menu in extensionMenus" :key="menu.index" :index="menu.index">
<el-menu-item :index="menu.index">
<el-icon><IconMenu /></el-icon>
<template #title>{{ menu.name }}</template>
</el-menu-item>
</span>
</el-menu>
</el-aside>

Expand All @@ -166,8 +180,11 @@ watch(theme, (e) => {
<DataManager v-else-if="panelName === 'data'" />
<MockManager v-else-if="panelName === 'mock'" />
<StoreManager v-else-if="panelName === 'store'" />
<SecretManager v-else-if="panelName === 'secret'" />
<WelcomePage v-else />
<WelcomePage v-else-if="panelName === 'welcome' || panelName === ''" />

<span v-for="menu in extensionMenus" :key="menu.index" :index="menu.index">
<Extension v-if="panelName === menu.index" :name="menu.name" />
</span>
</el-main>

<div style="position: absolute; bottom: 0px; right: 10px;">
Expand Down
51 changes: 51 additions & 0 deletions console/atest-ui/src/views/Extension.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script setup lang="ts">
import { API } from './net';

const props = defineProps({
name: String
})

const loadPlugin = async (): Promise<void> => {
try {
API.GetPageOfCSS(props.name, (d) => {
const style = document.createElement('style');
style.type = 'text/css';
style.textContent = d.message;
document.head.appendChild(style);
});

API.GetPageOfJS(props.name, (d) => {
const script = document.createElement('script');
script.type = 'text/javascript';
script.textContent = d.message;
document.head.appendChild(script);

// 类型安全的插件访问
const plugin = window.ATestPlugin;

if (plugin && plugin.mount) {
console.log('插件加载成功');
const container = document.getElementById("plugin-container");
plugin.mount(container, {
message: '来自宿主的消息'
});
}
});
} catch (error) {
console.log(`加载失败: ${(error as Error).message}`)
} finally {
console.log('插件加载完成');
}
};
try {
loadPlugin();
} catch (error) {
console.error('插件加载失败:', error);
}
</script>

<template>
<div id="plugin-container">
{{ props.name }}
</div>
</template>
119 changes: 0 additions & 119 deletions console/atest-ui/src/views/SecretManager.vue

This file was deleted.

38 changes: 37 additions & 1 deletion console/atest-ui/src/views/net.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,42 @@ function GetVersion(callback?: (v: AppVersion) => void) {
.then(emptyOrDefault(callback))
}

const GetMenus = (callback?: (v: any) => void) => {
const requestOptions = {
method: 'GET',
headers: {
'X-Store-Name': 'vault'
},
}
fetch('/api/v1/extension/menus', requestOptions)
.then(DefaultResponseProcess)
.then(emptyOrDefault(callback))
}

const GetPageOfJS = (name: string, callback?: (v: CommonResult) => void) => {
const requestOptions = {
method: 'GET',
headers: {
'X-Store-Name': 'vault'
},
}
fetch(`/api/v1/extension/pages/${name}/js`, requestOptions)
.then(DefaultResponseProcess)
.then(emptyOrDefault(callback))
}

const GetPageOfCSS = (name: string, callback?: (v: CommonResult) => void) => {
const requestOptions = {
method: 'GET',
headers: {
'X-Store-Name': 'vault'
},
}
fetch(`/api/v1/extension/pages/${name}/css`, requestOptions)
.then(DefaultResponseProcess)
.then(emptyOrDefault(callback))
}

interface CommonResult {
message: string
success: boolean
Expand Down Expand Up @@ -965,7 +1001,7 @@ const GetBinding = (name: string, callback: (d: any) => void | null) => {

export const API = {
DefaultResponseProcess,
GetVersion, GetSchema,
GetVersion, GetSchema, GetMenus, GetPageOfJS, GetPageOfCSS,
CreateTestSuite, UpdateTestSuite, ImportTestSuite, GetTestSuite, DeleteTestSuite, ConvertTestSuite, DuplicateTestSuite, RenameTestSuite, GetTestSuiteYaml,
CreateTestCase, UpdateTestCase, GetTestCase, ListTestCase, DeleteTestCase, DuplicateTestCase, RenameTestCase, RunTestCase, BatchRunTestCase,
GetHistoryTestCaseWithResult, DeleteHistoryTestCase, GetHistoryTestCase, GetTestCaseAllHistory, DeleteAllHistoryTestCase, DownloadResponseFile,
Expand Down
2 changes: 1 addition & 1 deletion pkg/runner/monitor/monitor.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/runner/monitor/monitor_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading