forked from github/copilot-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-tradingview-chart-verification.js
More file actions
210 lines (182 loc) · 9.2 KB
/
test-tradingview-chart-verification.js
File metadata and controls
210 lines (182 loc) · 9.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/usr/bin/env node
const assert = require('assert');
const path = require('path');
const { getTradingViewShortcutKey } = require(path.join(__dirname, '..', 'src', 'main', 'tradingview', 'shortcut-profile.js'));
const {
extractRequestedTimeframe,
extractRequestedSymbol,
extractRequestedWatchlistSymbol,
inferTradingViewTimeframeIntent,
inferTradingViewSymbolIntent,
inferTradingViewWatchlistIntent,
buildTradingViewTimeframeWorkflowActions,
buildTradingViewSymbolWorkflowActions,
buildTradingViewWatchlistWorkflowActions,
maybeRewriteTradingViewTimeframeWorkflow,
maybeRewriteTradingViewSymbolWorkflow,
maybeRewriteTradingViewWatchlistWorkflow
} = require(path.join(__dirname, '..', 'src', 'main', 'tradingview', 'chart-verification.js'));
function test(name, fn) {
try {
fn();
console.log(`PASS ${name}`);
} catch (error) {
console.error(`FAIL ${name}`);
console.error(error.stack || error.message);
process.exitCode = 1;
}
}
test('extractRequestedTimeframe normalizes common TradingView timeframe phrases', () => {
assert.strictEqual(extractRequestedTimeframe('change the timeframe selector from 1m to 5m in tradingview'), '5m');
assert.strictEqual(extractRequestedTimeframe('switch tradingview to 1 hour timeframe'), '1h');
assert.strictEqual(extractRequestedTimeframe('set the chart interval to 4 hours'), '4h');
});
test('extractRequestedTimeframe does not throw on Pine authoring prompts with no timeframe intent', () => {
assert.doesNotThrow(() => {
const timeframe = extractRequestedTimeframe('tradingview application is in the background, create a pine script that shows confidence in volume and momentum. then use key ctrl + enter to apply to the LUNR chart.');
assert.strictEqual(timeframe, null);
});
});
test('inferTradingViewTimeframeIntent recognizes selector-style timeframe workflows', () => {
const intent = inferTradingViewTimeframeIntent('change the timeframe selector from 1m to 5m in tradingview');
assert(intent, 'intent should be inferred');
assert.strictEqual(intent.appName, 'TradingView');
assert.strictEqual(intent.timeframe, '5m');
assert.strictEqual(intent.selectorContext, true);
});
test('extractRequestedSymbol normalizes common TradingView symbol phrases', () => {
assert.strictEqual(extractRequestedSymbol('change the symbol to NVDA in tradingview'), 'NVDA');
assert.strictEqual(extractRequestedSymbol('search for ticker msft in tradingview'), 'MSFT');
assert.strictEqual(extractRequestedSymbol('set the ticker to spy on tradingview'), 'SPY');
assert.strictEqual(extractRequestedSymbol('open Pine Editor for the LUNR chart in tradingview'), 'LUNR');
});
test('inferTradingViewSymbolIntent recognizes symbol-change workflows', () => {
const intent = inferTradingViewSymbolIntent('change the symbol to NVDA in tradingview');
assert(intent, 'symbol intent should be inferred');
assert.strictEqual(intent.appName, 'TradingView');
assert.strictEqual(intent.symbol, 'NVDA');
});
test('inferTradingViewSymbolIntent recognizes shortcut-alias quick-search phrasing', () => {
const intent = inferTradingViewSymbolIntent('open the command palette for NVDA in tradingview');
assert(intent, 'quick-search alias intent should be inferred');
assert.strictEqual(intent.appName, 'TradingView');
assert.strictEqual(intent.symbol, 'NVDA');
assert.strictEqual(intent.searchContext, true);
});
test('extractRequestedWatchlistSymbol normalizes common TradingView watchlist phrases', () => {
assert.strictEqual(extractRequestedWatchlistSymbol('select the watchlist symbol NVDA in tradingview'), 'NVDA');
assert.strictEqual(extractRequestedWatchlistSymbol('switch the watch list to msft in tradingview'), 'MSFT');
});
test('inferTradingViewWatchlistIntent recognizes watchlist workflows', () => {
const intent = inferTradingViewWatchlistIntent('select the watchlist symbol NVDA in tradingview');
assert(intent, 'watchlist intent should be inferred');
assert.strictEqual(intent.appName, 'TradingView');
assert.strictEqual(intent.symbol, 'NVDA');
});
test('buildTradingViewTimeframeWorkflowActions emits bounded timeframe confirmation flow', () => {
const actions = buildTradingViewTimeframeWorkflowActions({ appName: 'TradingView', timeframe: '5m' });
assert.strictEqual(actions[0].type, 'bring_window_to_front');
assert.strictEqual(actions[2].type, 'type');
assert.strictEqual(actions[2].text, '5m');
assert.strictEqual(actions[4].type, 'key');
assert.strictEqual(actions[4].key, 'enter');
assert.strictEqual(actions[4].verify.kind, 'timeframe-updated');
assert(actions[4].verify.keywords.includes('5m'));
});
test('maybeRewriteTradingViewTimeframeWorkflow rewrites low-signal timeframe plans', () => {
const rewritten = maybeRewriteTradingViewTimeframeWorkflow([
{ type: 'screenshot' },
{ type: 'wait', ms: 250 }
], {
userMessage: 'change the timeframe selector from 1m to 5m in tradingview'
});
assert(Array.isArray(rewritten), 'low-signal timeframe request should rewrite');
assert.strictEqual(rewritten[2].text, '5m');
assert.strictEqual(rewritten[4].key, 'enter');
assert.strictEqual(rewritten[4].verify.target, 'timeframe-updated');
});
test('buildTradingViewSymbolWorkflowActions emits bounded symbol confirmation flow', () => {
const actions = buildTradingViewSymbolWorkflowActions({ appName: 'TradingView', symbol: 'NVDA' });
assert.strictEqual(actions[0].type, 'bring_window_to_front');
assert.strictEqual(actions[2].type, 'type');
assert.strictEqual(actions[2].text, 'NVDA');
assert.strictEqual(actions[4].type, 'key');
assert.strictEqual(actions[4].key, 'enter');
assert.strictEqual(actions[4].verify.kind, 'symbol-updated');
assert(actions[4].verify.keywords.includes('NVDA'));
});
test('maybeRewriteTradingViewSymbolWorkflow rewrites low-signal symbol plans', () => {
const rewritten = maybeRewriteTradingViewSymbolWorkflow([
{ type: 'screenshot' },
{ type: 'wait', ms: 250 }
], {
userMessage: 'change the symbol to NVDA in tradingview'
});
assert(Array.isArray(rewritten), 'low-signal symbol request should rewrite');
assert.strictEqual(rewritten[2].text, 'NVDA');
assert.strictEqual(rewritten[4].key, 'enter');
assert.strictEqual(rewritten[4].verify.target, 'symbol-updated');
});
test('maybeRewriteTradingViewSymbolWorkflow rewrites low-signal quick-search alias plans', () => {
const rewritten = maybeRewriteTradingViewSymbolWorkflow([
{ type: 'screenshot' },
{ type: 'wait', ms: 250 }
], {
userMessage: 'open the quick search for MSFT in tradingview'
});
assert(Array.isArray(rewritten), 'quick-search alias request should rewrite');
assert.strictEqual(rewritten[2].text, 'MSFT');
assert.strictEqual(rewritten[4].key, 'enter');
assert(rewritten[4].verify.keywords.includes('quick-search'));
assert(rewritten[4].verify.keywords.includes('command palette'));
});
test('maybeRewriteTradingViewSymbolWorkflow does not replace plans already using symbol-search shortcut', () => {
const rewritten = maybeRewriteTradingViewSymbolWorkflow([
{ type: 'bring_window_to_front', title: 'TradingView', processName: 'tradingview' },
{ type: 'key', key: getTradingViewShortcutKey('symbol-search') },
{ type: 'type', text: 'MSFT' },
{ type: 'key', key: 'enter' }
], {
userMessage: 'open the command palette for MSFT in tradingview'
});
assert.strictEqual(rewritten, null);
});
test('buildTradingViewWatchlistWorkflowActions emits bounded watchlist confirmation flow', () => {
const actions = buildTradingViewWatchlistWorkflowActions({ appName: 'TradingView', symbol: 'NVDA' });
assert.strictEqual(actions[0].type, 'bring_window_to_front');
assert.strictEqual(actions[2].type, 'type');
assert.strictEqual(actions[2].text, 'NVDA');
assert.strictEqual(actions[4].type, 'key');
assert.strictEqual(actions[4].key, 'enter');
assert.strictEqual(actions[4].verify.kind, 'watchlist-updated');
assert(actions[4].verify.keywords.includes('watchlist'));
});
test('maybeRewriteTradingViewWatchlistWorkflow rewrites low-signal watchlist plans', () => {
const rewritten = maybeRewriteTradingViewWatchlistWorkflow([
{ type: 'screenshot' },
{ type: 'wait', ms: 250 }
], {
userMessage: 'select the watchlist symbol NVDA in tradingview'
});
assert(Array.isArray(rewritten), 'low-signal watchlist request should rewrite');
assert.strictEqual(rewritten[2].text, 'NVDA');
assert.strictEqual(rewritten[4].key, 'enter');
assert.strictEqual(rewritten[4].verify.target, 'watchlist-updated');
});
test('symbol workflow does not hijack passive TradingView analysis prompts', () => {
const rewritten = maybeRewriteTradingViewSymbolWorkflow([
{ type: 'screenshot' },
{ type: 'wait', ms: 250 }
], {
userMessage: 'help me make a confident synthesis of ticker LUNR in tradingview'
});
assert.strictEqual(rewritten, null);
});
test('symbol workflow does not hijack TradingView Pine authoring prompts that mention a chart symbol', () => {
const rewritten = maybeRewriteTradingViewSymbolWorkflow([
{ type: 'focus_window', windowHandle: 459522 }
], {
userMessage: 'tradingview application is in the background, create a pine script that shows confidence in volume and momentum. then use key ctrl + enter to apply to the LUNR chart.'
});
assert.strictEqual(rewritten, null);
});