Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
49 changes: 49 additions & 0 deletions console/atest-ui/src/views/Extension.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { API } from './net';

interface Props {
name: string
}
const props = defineProps<Props>()

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('extension load success');
const container = document.getElementById("plugin-container");
plugin.mount(container);
}
});
} catch (error) {
console.log(`extension load error: ${(error as Error).message}`)
} finally {
console.log('extension load finally');
}
};
try {
loadPlugin();
} catch (error) {
console.error('extension load error:', error);
}
</script>

<template>
<div id="plugin-container">
{{ props.name }}
</div>
</template>
33 changes: 28 additions & 5 deletions console/atest-ui/src/views/MockManager.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { ElMessage } from 'element-plus'
import yaml from 'js-yaml';
import { jsonSchema } from "codemirror-json-schema";
import { NewTemplateLangComplete, NewHeaderLangComplete } from './languageComplete'
Expand Down Expand Up @@ -34,6 +35,10 @@ interface MockConfig {
ConfigAsJSON: string
Prefix: string
Port: number
storeKind: string
storeLocalFile?: string
storeURL?: string
storeRemote?: string
}

const tabActive = ref('yaml')
Expand Down Expand Up @@ -64,10 +69,18 @@ function jsonToYaml(jsonData: object | string): string {
}

const link = ref('')
API.GetMockConfig((d) => {
mockConfig.value = d
link.value = `http://${window.location.hostname}:${d.Port}${d.Prefix}/api.json`
})
const loadConfig = () => {
API.GetMockConfig((d) => {
ElMessage({
showClose: true,
message: 'Config loaded!',
type: 'success'
});
mockConfig.value = d
link.value = `http://${window.location.hostname}:${d.Port}${d.Prefix}/api.json`
})
}
loadConfig()
const prefixChanged = (p: string) => {
mockConfig.value.Prefix = p
}
Expand Down Expand Up @@ -96,13 +109,23 @@ items:
<template>
<div>
<el-button type="primary" @click="insertSample">{{t('button.insertSample')}}</el-button>
<el-button type="warning" @click="API.ReloadMockServer(mockConfig)">{{t('button.reload')}}</el-button>
<el-button type="warning" @click="API.ReloadMockServer(mockConfig).then(() => loadConfig())">{{t('button.reload')}}</el-button>
<el-divider direction="vertical" />
<el-link target="_blank" :href="link">{{ link }}</el-link> <!-- Noncompliant -->
</div>
<div class="config">
API Prefix:<EditButton :value="mockConfig.Prefix" @changed="prefixChanged"/>
Port:<EditButton :value="mockConfig.Port" @changed="portChanged"/>
Store:
<el-select v-model="mockConfig.storeKind" placeholder="Select Store Kind">
<el-option label="Memory" value="memory"></el-option>
<el-option label="Local File" value="localFile"></el-option>
<el-option label="Remote" value="remote"></el-option>
<el-option label="URL" value="url"></el-option>
</el-select>
<span v-if="mockConfig.storeKind === 'localFile'">
File:<el-input v-model="mockConfig.storeLocalFile" placeholder="Local File Path"></el-input>
</span>
</div>
<el-splitter layout="vertical" style="height: calc(100vh - 100px);">
<el-splitter-panel size="70%">
Expand Down
119 changes: 0 additions & 119 deletions console/atest-ui/src/views/SecretManager.vue

This file was deleted.

Loading
Loading