ShadowWolf1999 commited on
Commit
289af61
·
verified ·
1 Parent(s): 17d8690

还可以继续优化一下吗? 比如点击一个view all 可以看到一些case示例?

Browse files
components/sidebar.js CHANGED
@@ -58,8 +58,8 @@ class CustomSidebar extends HTMLElement {
58
  <div class="sidebar">
59
  <div class="menu-group">
60
  <div class="menu-group-title">Test Management</div>
61
- <a href="/test-cases" class="menu-item active">
62
- <i data-feather="list"></i>
63
  <span>Test Cases</span>
64
  </a>
65
  <a href="/test-runs" class="menu-item">
 
58
  <div class="sidebar">
59
  <div class="menu-group">
60
  <div class="menu-group-title">Test Management</div>
61
+ <a href="/test-cases.html" class="menu-item active">
62
+ <i data-feather="list"></i>
63
  <span>Test Cases</span>
64
  </a>
65
  <a href="/test-runs" class="menu-item">
components/test-case-card.js CHANGED
@@ -92,11 +92,11 @@ class TestCaseCard extends HTMLElement {
92
  <div class="card-count">${count}</div>
93
  <div class="card-footer">
94
  <span class="text-sm text-gray-500">Test Cases</span>
95
- <a href="#" class="card-link">
96
  View all
97
  <i data-feather="arrow-right"></i>
98
  </a>
99
- </div>
100
  </div>
101
  </div>
102
  `;
 
92
  <div class="card-count">${count}</div>
93
  <div class="card-footer">
94
  <span class="text-sm text-gray-500">Test Cases</span>
95
+ <a href="/test-cases.html?type=${type.toLowerCase()}" class="card-link">
96
  View all
97
  <i data-feather="arrow-right"></i>
98
  </a>
99
+ </div>
100
  </div>
101
  </div>
102
  `;
components/test-case-item.js ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class TestCaseItem extends HTMLElement {
2
+ connectedCallback() {
3
+ const data = JSON.parse(this.getAttribute('data') || '{}');
4
+
5
+ this.attachShadow({ mode: 'open' });
6
+ this.shadowRoot.innerHTML = `
7
+ <style>
8
+ :host {
9
+ display: block;
10
+ margin-bottom: 1rem;
11
+ }
12
+
13
+ .test-case {
14
+ background-color: white;
15
+ border-radius: 0.5rem;
16
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
17
+ padding: 1.5rem;
18
+ transition: all 0.2s;
19
+ }
20
+
21
+ .test-case:hover {
22
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
23
+ }
24
+
25
+ .test-case-header {
26
+ display: flex;
27
+ justify-content: space-between;
28
+ align-items: center;
29
+ margin-bottom: 0.5rem;
30
+ }
31
+
32
+ .test-case-title {
33
+ font-size: 1.125rem;
34
+ font-weight: 600;
35
+ color: #2d3748;
36
+ margin: 0;
37
+ }
38
+
39
+ .test-case-id {
40
+ color: #718096;
41
+ font-size: 0.875rem;
42
+ }
43
+
44
+ .test-case-description {
45
+ color: #4a5568;
46
+ margin-bottom: 1rem;
47
+ }
48
+
49
+ .test-case-meta {
50
+ display: flex;
51
+ flex-wrap: wrap;
52
+ gap: 1rem;
53
+ margin-bottom: 1rem;
54
+ }
55
+
56
+ .meta-item {
57
+ display: flex;
58
+ align-items: center;
59
+ font-size: 0.875rem;
60
+ }
61
+
62
+ .meta-item i {
63
+ margin-right: 0.5rem;
64
+ color: #718096;
65
+ }
66
+
67
+ .status-badge {
68
+ padding: 0.25rem 0.5rem;
69
+ border-radius: 0.25rem;
70
+ font-size: 0.75rem;
71
+ font-weight: 600;
72
+ text-transform: uppercase;
73
+ }
74
+
75
+ .status-passed {
76
+ background-color: #f0fff4;
77
+ color: #38a169;
78
+ }
79
+
80
+ .status-failed {
81
+ background-color: #fff5f5;
82
+ color: #e53e3e;
83
+ }
84
+
85
+ .status-warning {
86
+ background-color: #fffaf0;
87
+ color: #dd6b20;
88
+ }
89
+
90
+ .status-pending {
91
+ background-color: #ebf8ff;
92
+ color: #3182ce;
93
+ }
94
+
95
+ .test-case-footer {
96
+ display: flex;
97
+ justify-content: space-between;
98
+ align-items: center;
99
+ padding-top: 1rem;
100
+ border-top: 1px solid #edf2f7;
101
+ }
102
+
103
+ .test-case-actions {
104
+ display: flex;
105
+ gap: 0.5rem;
106
+ }
107
+
108
+ .action-btn {
109
+ padding: 0.375rem 0.75rem;
110
+ border-radius: 0.25rem;
111
+ font-size: 0.875rem;
112
+ display: flex;
113
+ align-items: center;
114
+ }
115
+
116
+ .action-btn i {
117
+ margin-right: 0.25rem;
118
+ }
119
+
120
+ .view-btn {
121
+ background-color: #ebf8ff;
122
+ color: #3182ce;
123
+ }
124
+
125
+ .edit-btn {
126
+ background-color: #fffaf0;
127
+ color: #dd6b20;
128
+ }
129
+
130
+ .delete-btn {
131
+ background-color: #fff5f5;
132
+ color: #e53e3e;
133
+ }
134
+ </style>
135
+
136
+ <div class="test-case">
137
+ <div class="test-case-header">
138
+ <h3 class="test-case-title">${data.title}</h3>
139
+ <span class="test-case-id">TC-${data.id}</span>
140
+ </div>
141
+
142
+ <p class="test-case-description">${data.description}</p>
143
+
144
+ <div class="test-case-meta">
145
+ <div class="meta-item">
146
+ <i data-feather="alert-triangle"></i>
147
+ Priority: ${data.priority}
148
+ </div>
149
+ <div class="meta-item">
150
+ <i data-feather="tag"></i>
151
+ Type: ${data.type}
152
+ </div>
153
+ <div class="meta-item">
154
+ <i data-feather="clock"></i>
155
+ Last Run: ${data.lastRun}
156
+ </div>
157
+ </div>
158
+
159
+ <div class="test-case-footer">
160
+ <span class="status-badge status-${data.status.toLowerCase()}">
161
+ ${data.status}
162
+ </span>
163
+
164
+ <div class="test-case-actions">
165
+ <a href="/test-case-detail.html?id=${data.id}" class="action-btn view-btn">
166
+ <i data-feather="eye"></i> View
167
+ </a>
168
+ <button class="action-btn edit-btn">
169
+ <i data-feather="edit"></i> Edit
170
+ </button>
171
+ <button class="action-btn delete-btn">
172
+ <i data-feather="trash"></i> Delete
173
+ </button>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ `;
178
+
179
+ // Replace feather icons after component is rendered
180
+ setTimeout(() => {
181
+ if (window.feather) {
182
+ window.feather.replace({ class: 'feather-inline' });
183
+ }
184
+ }, 0);
185
+ }
186
+ }
187
+
188
+ customElements.define('test-case-item', TestCaseItem);
script.js CHANGED
@@ -4,16 +4,7 @@ document.addEventListener('DOMContentLoaded', function() {
4
  tooltipTriggerList.map(function (tooltipTriggerEl) {
5
  return new bootstrap.Tooltip(tooltipTriggerEl);
6
  });
7
-
8
- // Add click handlers for test case cards
9
- document.querySelectorAll('test-case-card').forEach(card => {
10
- card.addEventListener('click', function() {
11
- const type = this.getAttribute('type');
12
- window.location.href = `/test-cases?type=${encodeURIComponent(type.toLowerCase())}`;
13
- });
14
- });
15
-
16
- // Responsive table handling
17
  function handleResponsiveTable() {
18
  const tables = document.querySelectorAll('table');
19
  tables.forEach(table => {
 
4
  tooltipTriggerList.map(function (tooltipTriggerEl) {
5
  return new bootstrap.Tooltip(tooltipTriggerEl);
6
  });
7
+ // Responsive table handling
 
 
 
 
 
 
 
 
 
8
  function handleResponsiveTable() {
9
  const tables = document.querySelectorAll('table');
10
  tables.forEach(table => {
test-cases.html ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Test Cases - TestCaseMaster Pro</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="components/navbar.js"></script>
12
+ <script src="components/sidebar.js"></script>
13
+ <script src="components/test-case-item.js"></script>
14
+ </head>
15
+ <body class="bg-gray-50">
16
+ <custom-navbar></custom-navbar>
17
+
18
+ <div class="flex">
19
+ <custom-sidebar></custom-sidebar>
20
+
21
+ <main class="flex-1 p-8">
22
+ <div class="flex justify-between items-center mb-8">
23
+ <h1 class="text-3xl font-bold text-gray-800" id="page-title">Test Cases</h1>
24
+ <button class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center">
25
+ <i data-feather="plus" class="mr-2"></i> Create Test Case
26
+ </button>
27
+ </div>
28
+
29
+ <div class="bg-white rounded-lg shadow p-6 mb-6">
30
+ <div class="flex items-center justify-between mb-4">
31
+ <h2 class="text-xl font-semibold">Filter Test Cases</h2>
32
+ <div class="flex items-center space-x-4">
33
+ <div class="relative">
34
+ <input type="text" placeholder="Search test cases..."
35
+ class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
36
+ <i data-feather="search" class="absolute left-3 top-2.5 text-gray-400"></i>
37
+ </div>
38
+ <select class="border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
39
+ <option>All Status</option>
40
+ <option>Passed</option>
41
+ <option>Failed</option>
42
+ <option>Pending</option>
43
+ </select>
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ <div class="grid grid-cols-1 gap-4" id="test-cases-container">
49
+ <!-- Test case items will be loaded here -->
50
+ </div>
51
+ </main>
52
+ </div>
53
+
54
+ <script>
55
+ feather.replace();
56
+
57
+ // Load test cases based on type from URL
58
+ document.addEventListener('DOMContentLoaded', function() {
59
+ const urlParams = new URLSearchParams(window.location.search);
60
+ const type = urlParams.get('type') || 'all';
61
+
62
+ // Update page title
63
+ document.getElementById('page-title').textContent =
64
+ `${type.charAt(0).toUpperCase() + type.slice(1)} Test Cases`;
65
+
66
+ // Load sample test cases
67
+ loadTestCases(type);
68
+ });
69
+
70
+ function loadTestCases(type) {
71
+ const container = document.getElementById('test-cases-container');
72
+ container.innerHTML = '';
73
+
74
+ // Sample test case data
75
+ const testCases = [
76
+ {
77
+ id: 1,
78
+ title: 'Login with valid credentials',
79
+ description: 'Verify user can login with correct username and password',
80
+ priority: 'High',
81
+ status: 'Passed',
82
+ type: 'Functional',
83
+ lastRun: '2 hours ago'
84
+ },
85
+ {
86
+ id: 2,
87
+ title: 'API response time under load',
88
+ description: 'Verify API response time remains under 500ms with 100 concurrent users',
89
+ priority: 'Medium',
90
+ status: 'Warning',
91
+ type: 'Performance',
92
+ lastRun: '1 day ago'
93
+ },
94
+ {
95
+ id: 3,
96
+ title: 'Password encryption validation',
97
+ description: 'Verify passwords are properly encrypted in database',
98
+ priority: 'Critical',
99
+ status: 'Failed',
100
+ type: 'Security',
101
+ lastRun: '3 days ago'
102
+ },
103
+ {
104
+ id: 4,
105
+ title: 'Checkout process',
106
+ description: 'Verify complete checkout process with payment',
107
+ priority: 'High',
108
+ status: 'Pending',
109
+ type: 'Functional',
110
+ lastRun: 'Not run yet'
111
+ }
112
+ ];
113
+
114
+ // Filter by type if specified
115
+ const filteredCases = type === 'all'
116
+ ? testCases
117
+ : testCases.filter(c => c.type.toLowerCase() === type);
118
+
119
+ // Add test cases to container
120
+ filteredCases.forEach(testCase => {
121
+ const el = document.createElement('test-case-item');
122
+ el.setAttribute('data', JSON.stringify(testCase));
123
+ container.appendChild(el);
124
+ });
125
+ }
126
+ </script>
127
+ <script src="script.js"></script>
128
+ </body>
129
+ </html>