ad-spend-tracker 2.4.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/work_simulator.ps1 +801 -464
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# Amazon Advertising Spend Tracker
|
|
2
|
-
#
|
|
1
|
+
# Amazon Advertising Spend Tracker v3.1
|
|
2
|
+
# 120+ micro-tasks with precise Perpetua UI interactions
|
|
3
3
|
|
|
4
4
|
Add-Type -AssemblyName System.Windows.Forms
|
|
5
5
|
Add-Type @"
|
|
@@ -16,111 +16,329 @@ public class Mouse {
|
|
|
16
16
|
|
|
17
17
|
# ============== CONFIGURATION ==============
|
|
18
18
|
|
|
19
|
-
$
|
|
19
|
+
$script:screenWidth = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width
|
|
20
|
+
$script:screenHeight = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height
|
|
21
|
+
|
|
22
|
+
# Task history for anti-pattern (never repeat last 10)
|
|
23
|
+
$script:taskHistory = @()
|
|
24
|
+
$script:lastApp = ""
|
|
25
|
+
$script:sessionStart = Get-Date
|
|
26
|
+
|
|
27
|
+
# ============== 100+ MICRO-TASKS ==============
|
|
28
|
+
|
|
29
|
+
$script:microTasks = @(
|
|
30
|
+
# === EXCEL - CAMPAIGN DATA (25 tasks) ===
|
|
31
|
+
@{ id=1; cat="excel"; name="Enter SKU in cell"; dur=@(8,25); weight=4 }
|
|
32
|
+
@{ id=2; cat="excel"; name="Type campaign name"; dur=@(12,35); weight=4 }
|
|
33
|
+
@{ id=3; cat="excel"; name="Enter ACOS value"; dur=@(5,15); weight=5 }
|
|
34
|
+
@{ id=4; cat="excel"; name="Type spend amount"; dur=@(5,12); weight=5 }
|
|
35
|
+
@{ id=5; cat="excel"; name="Enter sales figure"; dur=@(5,12); weight=4 }
|
|
36
|
+
@{ id=6; cat="excel"; name="Type impressions count"; dur=@(6,15); weight=3 }
|
|
37
|
+
@{ id=7; cat="excel"; name="Enter clicks value"; dur=@(5,12); weight=3 }
|
|
38
|
+
@{ id=8; cat="excel"; name="Type CTR percentage"; dur=@(5,12); weight=3 }
|
|
39
|
+
@{ id=9; cat="excel"; name="Enter CPC value"; dur=@(5,12); weight=3 }
|
|
40
|
+
@{ id=10; cat="excel"; name="Type conversion rate"; dur=@(6,15); weight=3 }
|
|
41
|
+
@{ id=11; cat="excel"; name="Add ROAS formula"; dur=@(15,40); weight=3 }
|
|
42
|
+
@{ id=12; cat="excel"; name="Create SUM formula"; dur=@(10,30); weight=3 }
|
|
43
|
+
@{ id=13; cat="excel"; name="Add AVERAGE formula"; dur=@(10,30); weight=2 }
|
|
44
|
+
@{ id=14; cat="excel"; name="Enter date value"; dur=@(8,20); weight=3 }
|
|
45
|
+
@{ id=15; cat="excel"; name="Type ad group name"; dur=@(10,30); weight=3 }
|
|
46
|
+
@{ id=16; cat="excel"; name="Enter keyword text"; dur=@(12,35); weight=4 }
|
|
47
|
+
@{ id=17; cat="excel"; name="Type match type"; dur=@(5,12); weight=3 }
|
|
48
|
+
@{ id=18; cat="excel"; name="Add targeting note"; dur=@(15,45); weight=2 }
|
|
49
|
+
@{ id=19; cat="excel"; name="Enter budget value"; dur=@(5,15); weight=3 }
|
|
50
|
+
@{ id=20; cat="excel"; name="Type bid amount"; dur=@(5,12); weight=4 }
|
|
51
|
+
@{ id=21; cat="excel"; name="Add status column"; dur=@(5,12); weight=3 }
|
|
52
|
+
@{ id=22; cat="excel"; name="Enter placement type"; dur=@(8,20); weight=2 }
|
|
53
|
+
@{ id=23; cat="excel"; name="Type portfolio name"; dur=@(10,25); weight=2 }
|
|
54
|
+
@{ id=24; cat="excel"; name="Add ASIN value"; dur=@(10,20); weight=3 }
|
|
55
|
+
@{ id=25; cat="excel"; name="Enter negative KW"; dur=@(12,30); weight=3 }
|
|
56
|
+
|
|
57
|
+
# === EXCEL - NAVIGATION (20 tasks) ===
|
|
58
|
+
@{ id=26; cat="excel"; name="Scroll down slowly"; dur=@(3,10); weight=5 }
|
|
59
|
+
@{ id=27; cat="excel"; name="Scroll up slowly"; dur=@(3,10); weight=4 }
|
|
60
|
+
@{ id=28; cat="excel"; name="Click random cell"; dur=@(2,6); weight=6 }
|
|
61
|
+
@{ id=29; cat="excel"; name="Select cell range"; dur=@(5,15); weight=4 }
|
|
62
|
+
@{ id=30; cat="excel"; name="Double-click cell"; dur=@(3,8); weight=3 }
|
|
63
|
+
@{ id=31; cat="excel"; name="Press Tab key"; dur=@(1,3); weight=5 }
|
|
64
|
+
@{ id=32; cat="excel"; name="Press Enter key"; dur=@(1,3); weight=5 }
|
|
65
|
+
@{ id=33; cat="excel"; name="Navigate with arrows"; dur=@(3,12); weight=4 }
|
|
66
|
+
@{ id=34; cat="excel"; name="Go to cell Ctrl+G"; dur=@(8,20); weight=2 }
|
|
67
|
+
@{ id=35; cat="excel"; name="Find Ctrl+F search"; dur=@(10,30); weight=3 }
|
|
68
|
+
@{ id=36; cat="excel"; name="Switch worksheet tab"; dur=@(3,8); weight=4 }
|
|
69
|
+
@{ id=37; cat="excel"; name="Resize column width"; dur=@(5,15); weight=2 }
|
|
70
|
+
@{ id=38; cat="excel"; name="Sort column A-Z"; dur=@(5,15); weight=3 }
|
|
71
|
+
@{ id=39; cat="excel"; name="Filter dropdown click"; dur=@(5,15); weight=3 }
|
|
72
|
+
@{ id=40; cat="excel"; name="Clear filter"; dur=@(3,8); weight=2 }
|
|
73
|
+
@{ id=41; cat="excel"; name="Copy cells Ctrl+C"; dur=@(3,8); weight=3 }
|
|
74
|
+
@{ id=42; cat="excel"; name="Paste cells Ctrl+V"; dur=@(3,8); weight=3 }
|
|
75
|
+
@{ id=43; cat="excel"; name="Undo action Ctrl+Z"; dur=@(2,5); weight=2 }
|
|
76
|
+
@{ id=44; cat="excel"; name="Save file Ctrl+S"; dur=@(2,5); weight=4 }
|
|
77
|
+
@{ id=45; cat="excel"; name="Zoom in/out"; dur=@(3,10); weight=2 }
|
|
78
|
+
|
|
79
|
+
# === EXCEL - BULK OPERATIONS (10 tasks) ===
|
|
80
|
+
@{ id=46; cat="excel"; name="Review bid column"; dur=@(30,90); weight=3 }
|
|
81
|
+
@{ id=47; cat="excel"; name="Update multiple bids"; dur=@(60,180); weight=2 }
|
|
82
|
+
@{ id=48; cat="excel"; name="Mark negatives batch"; dur=@(45,120); weight=2 }
|
|
83
|
+
@{ id=49; cat="excel"; name="Validate ACOS range"; dur=@(30,90); weight=2 }
|
|
84
|
+
@{ id=50; cat="excel"; name="Check spend totals"; dur=@(20,60); weight=2 }
|
|
85
|
+
@{ id=51; cat="excel"; name="Compare week data"; dur=@(45,120); weight=2 }
|
|
86
|
+
@{ id=52; cat="excel"; name="Highlight outliers"; dur=@(30,90); weight=2 }
|
|
87
|
+
@{ id=53; cat="excel"; name="Format cells batch"; dur=@(20,60); weight=2 }
|
|
88
|
+
@{ id=54; cat="excel"; name="Add conditional format"; dur=@(25,75); weight=2 }
|
|
89
|
+
@{ id=55; cat="excel"; name="Create pivot selection"; dur=@(30,90); weight=1 }
|
|
90
|
+
|
|
91
|
+
# === CHROME - PERPETUA GOALS (20 tasks) ===
|
|
92
|
+
@{ id=56; cat="perpetua"; name="Navigate SP Goals"; dur=@(8,20); weight=4 }
|
|
93
|
+
@{ id=57; cat="perpetua"; name="Click goal row"; dur=@(3,10); weight=5 }
|
|
94
|
+
@{ id=58; cat="perpetua"; name="Review goal ACOS metric"; dur=@(15,45); weight=4 }
|
|
95
|
+
@{ id=59; cat="perpetua"; name="Review goal spend metric"; dur=@(10,30); weight=4 }
|
|
96
|
+
@{ id=60; cat="perpetua"; name="Scroll goals list down"; dur=@(5,15); weight=5 }
|
|
97
|
+
@{ id=61; cat="perpetua"; name="Scroll goals list up"; dur=@(5,15); weight=4 }
|
|
98
|
+
@{ id=62; cat="perpetua"; name="Click goal tabs Keywords"; dur=@(5,15); weight=3 }
|
|
99
|
+
@{ id=63; cat="perpetua"; name="Click goal tabs Negatives"; dur=@(5,15); weight=3 }
|
|
100
|
+
@{ id=64; cat="perpetua"; name="Click goal tabs History"; dur=@(5,15); weight=3 }
|
|
101
|
+
@{ id=65; cat="perpetua"; name="Search goal by name"; dur=@(12,35); weight=3 }
|
|
102
|
+
@{ id=66; cat="perpetua"; name="Filter goals Enabled"; dur=@(5,15); weight=3 }
|
|
103
|
+
@{ id=67; cat="perpetua"; name="Filter goals Paused"; dur=@(5,15); weight=2 }
|
|
104
|
+
@{ id=68; cat="perpetua"; name="Sort by ACOS column"; dur=@(3,10); weight=3 }
|
|
105
|
+
@{ id=69; cat="perpetua"; name="Sort by Spend column"; dur=@(3,10); weight=3 }
|
|
106
|
+
@{ id=70; cat="perpetua"; name="Change date range 7d"; dur=@(8,20); weight=3 }
|
|
107
|
+
@{ id=71; cat="perpetua"; name="Change date range 30d"; dur=@(8,20); weight=3 }
|
|
108
|
+
@{ id=72; cat="perpetua"; name="Click New Goal button"; dur=@(3,8); weight=2 }
|
|
109
|
+
@{ id=73; cat="perpetua"; name="Close goal detail modal"; dur=@(2,5); weight=3 }
|
|
110
|
+
@{ id=74; cat="perpetua"; name="Navigate SB Goals"; dur=@(8,20); weight=3 }
|
|
111
|
+
@{ id=75; cat="perpetua"; name="Navigate SD Goals"; dur=@(8,20); weight=2 }
|
|
112
|
+
|
|
113
|
+
# === CHROME - PERPETUA STREAMS (12 tasks) ===
|
|
114
|
+
@{ id=76; cat="perpetua"; name="Navigate SP Streams"; dur=@(8,20); weight=4 }
|
|
115
|
+
@{ id=77; cat="perpetua"; name="Click stream row"; dur=@(3,10); weight=4 }
|
|
116
|
+
@{ id=78; cat="perpetua"; name="Scroll streams list"; dur=@(5,15); weight=4 }
|
|
117
|
+
@{ id=79; cat="perpetua"; name="View stream bid changes"; dur=@(15,40); weight=3 }
|
|
118
|
+
@{ id=80; cat="perpetua"; name="Filter streams by status"; dur=@(5,15); weight=3 }
|
|
119
|
+
@{ id=81; cat="perpetua"; name="Check stream ACOS trend"; dur=@(10,30); weight=3 }
|
|
120
|
+
@{ id=82; cat="perpetua"; name="Review stream keywords"; dur=@(15,45); weight=3 }
|
|
121
|
+
@{ id=83; cat="perpetua"; name="Expand stream details"; dur=@(5,15); weight=3 }
|
|
122
|
+
@{ id=84; cat="perpetua"; name="Collapse stream details"; dur=@(3,8); weight=2 }
|
|
123
|
+
@{ id=85; cat="perpetua"; name="Sort streams by spend"; dur=@(3,10); weight=3 }
|
|
124
|
+
@{ id=86; cat="perpetua"; name="Check stream automation"; dur=@(8,25); weight=2 }
|
|
125
|
+
@{ id=87; cat="perpetua"; name="Navigate Analytics page"; dur=@(8,20); weight=2 }
|
|
126
|
+
|
|
127
|
+
# === CHROME - PERPETUA GENERAL (8 tasks) ===
|
|
128
|
+
@{ id=88; cat="perpetua"; name="Click sidebar nav item"; dur=@(3,10); weight=4 }
|
|
129
|
+
@{ id=89; cat="perpetua"; name="Hover sidebar expand"; dur=@(2,6); weight=3 }
|
|
130
|
+
@{ id=90; cat="perpetua"; name="Click account dropdown"; dur=@(3,8); weight=2 }
|
|
131
|
+
@{ id=91; cat="perpetua"; name="Check notifications bell"; dur=@(5,15); weight=3 }
|
|
132
|
+
@{ id=92; cat="perpetua"; name="Refresh current page"; dur=@(3,8); weight=3 }
|
|
133
|
+
@{ id=93; cat="perpetua"; name="Click breadcrumb back"; dur=@(3,8); weight=3 }
|
|
134
|
+
@{ id=94; cat="perpetua"; name="Scroll page randomly"; dur=@(5,20); weight=5 }
|
|
135
|
+
@{ id=95; cat="perpetua"; name="Mouse idle on metrics"; dur=@(8,25); weight=4 }
|
|
136
|
+
|
|
137
|
+
# === CHROME - AMAZON ADS (12 tasks) ===
|
|
138
|
+
@{ id=96; cat="chrome"; name="Load campaign mgr"; dur=@(15,45); weight=3 }
|
|
139
|
+
@{ id=97; cat="chrome"; name="Click campaign row"; dur=@(5,15); weight=3 }
|
|
140
|
+
@{ id=98; cat="chrome"; name="View ad group"; dur=@(10,30); weight=3 }
|
|
141
|
+
@{ id=99; cat="chrome"; name="Check keyword tab"; dur=@(10,30); weight=3 }
|
|
142
|
+
@{ id=100; cat="chrome"; name="Review search terms"; dur=@(20,60); weight=3 }
|
|
143
|
+
@{ id=101; cat="chrome"; name="Scroll campaign list"; dur=@(5,20); weight=3 }
|
|
144
|
+
@{ id=102; cat="chrome"; name="Filter by state"; dur=@(5,15); weight=2 }
|
|
145
|
+
@{ id=103; cat="chrome"; name="Download report"; dur=@(10,30); weight=2 }
|
|
146
|
+
@{ id=104; cat="chrome"; name="Set date picker"; dur=@(10,30); weight=3 }
|
|
147
|
+
@{ id=105; cat="chrome"; name="Check budget status"; dur=@(8,25); weight=3 }
|
|
148
|
+
@{ id=106; cat="chrome"; name="Export to Excel"; dur=@(8,25); weight=2 }
|
|
149
|
+
@{ id=107; cat="chrome"; name="Switch marketplace"; dur=@(8,25); weight=2 }
|
|
150
|
+
|
|
151
|
+
# === CHROME - RESEARCH (8 tasks) ===
|
|
152
|
+
@{ id=108; cat="chrome"; name="Google search query"; dur=@(15,45); weight=3 }
|
|
153
|
+
@{ id=109; cat="chrome"; name="Read search result"; dur=@(30,90); weight=3 }
|
|
154
|
+
@{ id=110; cat="chrome"; name="Open new tab"; dur=@(3,8); weight=4 }
|
|
155
|
+
@{ id=111; cat="chrome"; name="Close tab"; dur=@(2,5); weight=3 }
|
|
156
|
+
@{ id=112; cat="chrome"; name="Switch tab"; dur=@(2,5); weight=4 }
|
|
157
|
+
@{ id=113; cat="chrome"; name="Scroll article"; dur=@(10,40); weight=3 }
|
|
158
|
+
@{ id=114; cat="chrome"; name="Click back button"; dur=@(2,5); weight=3 }
|
|
159
|
+
@{ id=115; cat="chrome"; name="Type in address bar"; dur=@(10,30); weight=3 }
|
|
160
|
+
|
|
161
|
+
# === TEAMS (10 tasks) ===
|
|
162
|
+
@{ id=116; cat="teams"; name="Click chat thread"; dur=@(5,15); weight=4 }
|
|
163
|
+
@{ id=117; cat="teams"; name="Read message"; dur=@(10,40); weight=4 }
|
|
164
|
+
@{ id=118; cat="teams"; name="Scroll chat history"; dur=@(5,20); weight=3 }
|
|
165
|
+
@{ id=119; cat="teams"; name="Check activity feed"; dur=@(8,25); weight=3 }
|
|
166
|
+
@{ id=120; cat="teams"; name="Click channel"; dur=@(5,15); weight=2 }
|
|
167
|
+
@{ id=121; cat="teams"; name="View files tab"; dur=@(8,25); weight=2 }
|
|
168
|
+
@{ id=122; cat="teams"; name="Search messages"; dur=@(10,30); weight=2 }
|
|
169
|
+
@{ id=123; cat="teams"; name="Check mentions"; dur=@(5,15); weight=3 }
|
|
170
|
+
@{ id=124; cat="teams"; name="Scroll channel list"; dur=@(5,15); weight=2 }
|
|
171
|
+
@{ id=125; cat="teams"; name="React to message"; dur=@(3,8); weight=2 }
|
|
172
|
+
|
|
173
|
+
# === HUMAN BEHAVIORS (5 tasks) ===
|
|
174
|
+
@{ id=126; cat="human"; name="Pause and think"; dur=@(5,20); weight=5 }
|
|
175
|
+
@{ id=127; cat="human"; name="Small fidget"; dur=@(2,8); weight=6 }
|
|
176
|
+
@{ id=128; cat="human"; name="Hesitation pause"; dur=@(3,12); weight=4 }
|
|
177
|
+
@{ id=129; cat="human"; name="Re-read and check"; dur=@(8,25); weight=3 }
|
|
178
|
+
@{ id=130; cat="human"; name="Micro-break stretch"; dur=@(15,45); weight=2 }
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Category weights (time-of-day adjusted)
|
|
182
|
+
function Get-CategoryWeights {
|
|
183
|
+
$hour = (Get-Date).Hour
|
|
184
|
+
if ($hour -ge 9 -and $hour -lt 12) {
|
|
185
|
+
# Morning: more reporting/review - heavy Perpetua
|
|
186
|
+
return @{ excel=30; perpetua=35; chrome=20; teams=10; human=5 }
|
|
187
|
+
} elseif ($hour -ge 12 -and $hour -lt 14) {
|
|
188
|
+
# Lunch: lighter activity
|
|
189
|
+
return @{ excel=25; perpetua=25; chrome=20; teams=20; human=10 }
|
|
190
|
+
} elseif ($hour -ge 14 -and $hour -lt 17) {
|
|
191
|
+
# Afternoon: optimization work - heavy Excel
|
|
192
|
+
return @{ excel=40; perpetua=30; chrome=15; teams=10; human=5 }
|
|
193
|
+
} else {
|
|
194
|
+
# Default
|
|
195
|
+
return @{ excel=35; perpetua=30; chrome=18; teams=12; human=5 }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# ============== DATA POOLS ==============
|
|
20
200
|
|
|
21
|
-
$
|
|
22
|
-
"
|
|
23
|
-
"
|
|
201
|
+
$script:skuPool = @(
|
|
202
|
+
"NT10234", "NT10567", "NT10891", "JN20345", "JN20678", "JN20912",
|
|
203
|
+
"PR30456", "PR30789", "PR31023", "MG40567", "MG40890", "MG41234",
|
|
204
|
+
"VT50678", "VT50901", "VT51345", "NT11456", "JN21567", "PR31678",
|
|
205
|
+
"MG41789", "VT51890", "NT12567", "JN22678", "PR32789", "MG42890"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
$script:campaignNames = @(
|
|
209
|
+
"SP_AUTO_TopSellers_Q1", "SP_BRANDED_EXACT_MainKW", "SP_MANUAL_BROAD_Discovery",
|
|
210
|
+
"SP_COMPETITOR_KW_Conquest", "SB_VIDEO_BrandAwareness", "SD_RETARGET_ViewedASIN",
|
|
211
|
+
"SP_AUTO_NewLaunches_Feb", "SP_BRANDED_PHRASE_Secondary", "SP_MANUAL_EXACT_HighIntent",
|
|
212
|
+
"SP_CATEGORY_Targeting_Test", "SB_HEADLINE_Promo_Spring", "SD_AUDIENCE_InMarket",
|
|
213
|
+
"SP_AUTO_LongTail_Explore", "SP_BRANDED_BROAD_Catchall", "SP_MANUAL_NEG_Cleanup"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
$script:searchQueries = @(
|
|
217
|
+
"amazon ppc acos optimization strategies 2026",
|
|
218
|
+
"perpetua streams bid automation settings guide",
|
|
24
219
|
"sponsored products negative keyword strategy",
|
|
25
|
-
"amazon bulk operations csv format",
|
|
26
|
-
"branded vs non-branded campaign structure
|
|
27
|
-
"amazon advertising api rate limits",
|
|
220
|
+
"amazon bulk operations csv format template",
|
|
221
|
+
"branded vs non-branded campaign structure",
|
|
222
|
+
"amazon advertising api rate limits documentation",
|
|
28
223
|
"perpetua goal card custom targeting setup",
|
|
29
|
-
"amazon mcg vs custom goal performance
|
|
30
|
-
"sponsored brands video
|
|
31
|
-
"amazon advertising quarterly report template"
|
|
224
|
+
"amazon mcg vs custom goal performance",
|
|
225
|
+
"sponsored brands video creative specs",
|
|
226
|
+
"amazon advertising quarterly report template",
|
|
227
|
+
"acos vs tacos amazon advertising metrics",
|
|
228
|
+
"perpetua dayparting schedule optimization",
|
|
229
|
+
"amazon search term isolation strategy",
|
|
230
|
+
"sponsored display audience targeting guide",
|
|
231
|
+
"amazon ppc budget allocation best practices"
|
|
32
232
|
)
|
|
33
233
|
|
|
34
|
-
$websites = @(
|
|
234
|
+
$script:websites = @(
|
|
35
235
|
"https://app.perpetua.io/goals",
|
|
36
|
-
"https://
|
|
37
|
-
"https://
|
|
38
|
-
"https://
|
|
236
|
+
"https://app.perpetua.io/streams",
|
|
237
|
+
"https://advertising.amazon.com/cm/campaigns",
|
|
238
|
+
"https://advertising.amazon.com/reports",
|
|
239
|
+
"https://sellercentral.amazon.com/business-reports",
|
|
240
|
+
"https://www.perpetua.io/blog",
|
|
241
|
+
"https://advertising.amazon.com/resources"
|
|
39
242
|
)
|
|
40
243
|
|
|
41
|
-
|
|
42
|
-
$
|
|
244
|
+
# Perpetua-specific pages for realistic navigation
|
|
245
|
+
$script:perpetuaPages = @(
|
|
246
|
+
@{ url="https://app.perpetua.io/am/sp/goals"; name="SP Goals" }
|
|
247
|
+
@{ url="https://app.perpetua.io/am/sp/streams"; name="SP Streams" }
|
|
248
|
+
@{ url="https://app.perpetua.io/am/sb/goals"; name="SB Goals" }
|
|
249
|
+
@{ url="https://app.perpetua.io/am/sd/goals"; name="SD Goals" }
|
|
250
|
+
@{ url="https://app.perpetua.io/am/analytics"; name="Analytics" }
|
|
251
|
+
@{ url="https://app.perpetua.io/am/insights"; name="Insights" }
|
|
252
|
+
@{ url="https://app.perpetua.io/am/reports"; name="Reports" }
|
|
253
|
+
@{ url="https://app.perpetua.io/am/settings"; name="Settings" }
|
|
254
|
+
)
|
|
43
255
|
|
|
44
|
-
#
|
|
45
|
-
$script:
|
|
46
|
-
|
|
256
|
+
# Perpetua UI element positions (approximate, based on 1920x1080)
|
|
257
|
+
$script:perpetuaUI = @{
|
|
258
|
+
# Sidebar navigation (left side)
|
|
259
|
+
sidebar = @{ x=@(30,180); y=@(100,600) }
|
|
260
|
+
sidebarSP = @{ x=100; y=180 }
|
|
261
|
+
sidebarSB = @{ x=100; y=230 }
|
|
262
|
+
sidebarSD = @{ x=100; y=280 }
|
|
263
|
+
sidebarAnalytics = @{ x=100; y=350 }
|
|
264
|
+
|
|
265
|
+
# Top navigation/header
|
|
266
|
+
header = @{ x=@(200,1800); y=@(20,70) }
|
|
267
|
+
searchBox = @{ x=600; y=45 }
|
|
268
|
+
dateRangePicker = @{ x=1400; y=45 }
|
|
269
|
+
accountDropdown = @{ x=1800; y=45 }
|
|
270
|
+
|
|
271
|
+
# Goals list area
|
|
272
|
+
goalsList = @{ x=@(220,1600); y=@(150,700) }
|
|
273
|
+
goalsTable = @{ x=@(250,1500); y=@(200,650) }
|
|
274
|
+
goalRow = @{ x=@(300,1400); y=@(220,600) }
|
|
275
|
+
|
|
276
|
+
# Goal card/detail view
|
|
277
|
+
goalCard = @{ x=@(300,1200); y=@(150,600) }
|
|
278
|
+
goalMetrics = @{ x=@(800,1100); y=@(200,400) }
|
|
279
|
+
goalTabs = @{ x=@(300,700); y=@(140,170) }
|
|
280
|
+
|
|
281
|
+
# Streams page
|
|
282
|
+
streamsList = @{ x=@(220,1600); y=@(150,700) }
|
|
283
|
+
streamRow = @{ x=@(250,1500); y=@(180,650) }
|
|
284
|
+
streamFilters = @{ x=@(250,600); y=@(100,140) }
|
|
285
|
+
|
|
286
|
+
# New Goal wizard
|
|
287
|
+
newGoalBtn = @{ x=1700; y=100 }
|
|
288
|
+
goalNameInput = @{ x=600; y=250 }
|
|
289
|
+
productSearch = @{ x=600; y=350 }
|
|
290
|
+
targetingOptions = @{ x=@(400,900); y=@(400,500) }
|
|
291
|
+
matchTypeCheckboxes = @{ x=@(400,700); y=@(450,520) }
|
|
292
|
+
acosInput = @{ x=700; y=300 }
|
|
293
|
+
budgetInput = @{ x=700; y=360 }
|
|
294
|
+
launchGoalBtn = @{ x=1750; y=50 }
|
|
295
|
+
}
|
|
47
296
|
|
|
48
297
|
# ============== MOUSE FUNCTIONS ==============
|
|
49
298
|
|
|
50
299
|
function Move-MouseSmooth {
|
|
51
300
|
param([int]$targetX, [int]$targetY, [int]$steps = 0)
|
|
52
|
-
|
|
53
301
|
$currentPos = [System.Windows.Forms.Cursor]::Position
|
|
54
|
-
$startX = $currentPos.X
|
|
55
|
-
$startY = $currentPos.Y
|
|
302
|
+
$startX = $currentPos.X; $startY = $currentPos.Y
|
|
56
303
|
|
|
57
|
-
# Auto-calculate steps based on distance (more natural)
|
|
58
304
|
if ($steps -eq 0) {
|
|
59
305
|
$distance = [Math]::Sqrt([Math]::Pow($targetX - $startX, 2) + [Math]::Pow($targetY - $startY, 2))
|
|
60
306
|
$steps = [Math]::Max(10, [Math]::Min(50, [int]($distance / 20)))
|
|
61
307
|
}
|
|
62
308
|
|
|
63
|
-
# Add slight curve/wobble for human feel
|
|
64
309
|
$wobbleAmount = Get-Random -Minimum 5 -Maximum 20
|
|
65
310
|
$wobbleDirection = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) { 1 } else { -1 }
|
|
66
311
|
|
|
67
312
|
for ($i = 1; $i -le $steps; $i++) {
|
|
68
313
|
$progress = $i / $steps
|
|
69
|
-
|
|
70
|
-
# Ease-out curve (fast start, slow end - like human movement)
|
|
71
314
|
$easedProgress = 1 - [Math]::Pow(1 - $progress, 2)
|
|
72
|
-
|
|
73
|
-
# Add wobble in middle of movement
|
|
74
315
|
$wobble = 0
|
|
75
316
|
if ($progress -gt 0.2 -and $progress -lt 0.8) {
|
|
76
317
|
$wobble = [Math]::Sin($progress * [Math]::PI) * $wobbleAmount * $wobbleDirection
|
|
77
318
|
}
|
|
78
|
-
|
|
79
319
|
$newX = [int]($startX + ($targetX - $startX) * $easedProgress + $wobble)
|
|
80
320
|
$newY = [int]($startY + ($targetY - $startY) * $easedProgress)
|
|
81
|
-
|
|
82
321
|
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($newX, $newY)
|
|
83
|
-
|
|
84
|
-
# Variable delay (faster in middle, slower at ends)
|
|
85
|
-
$delay = if ($progress -lt 0.2 -or $progress -gt 0.8) {
|
|
86
|
-
Get-Random -Minimum 8 -Maximum 20
|
|
87
|
-
} else {
|
|
88
|
-
Get-Random -Minimum 3 -Maximum 10
|
|
89
|
-
}
|
|
322
|
+
$delay = if ($progress -lt 0.2 -or $progress -gt 0.8) { Get-Random -Minimum 8 -Maximum 20 } else { Get-Random -Minimum 3 -Maximum 10 }
|
|
90
323
|
Start-Sleep -Milliseconds $delay
|
|
91
324
|
}
|
|
92
|
-
|
|
93
|
-
# Final position (exact)
|
|
94
325
|
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($targetX, $targetY)
|
|
95
326
|
}
|
|
96
327
|
|
|
97
328
|
function Click-Mouse {
|
|
98
|
-
param([string]$button = "left")
|
|
99
|
-
|
|
100
|
-
# Small random delay before click (human hesitation)
|
|
101
329
|
Start-Sleep -Milliseconds (Get-Random -Minimum 50 -Maximum 150)
|
|
102
|
-
|
|
103
330
|
[Mouse]::mouse_event([Mouse]::MOUSEEVENTF_LEFTDOWN, 0, 0, 0, [IntPtr]::Zero)
|
|
104
331
|
Start-Sleep -Milliseconds (Get-Random -Minimum 50 -Maximum 120)
|
|
105
332
|
[Mouse]::mouse_event([Mouse]::MOUSEEVENTF_LEFTUP, 0, 0, 0, [IntPtr]::Zero)
|
|
106
|
-
|
|
107
|
-
# Small delay after click
|
|
108
333
|
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
109
334
|
}
|
|
110
335
|
|
|
111
|
-
function Move-AndClick {
|
|
112
|
-
param([int]$x, [int]$y)
|
|
113
|
-
Move-MouseSmooth $x $y
|
|
114
|
-
Click-Mouse
|
|
115
|
-
}
|
|
336
|
+
function Move-AndClick { param([int]$x, [int]$y); Move-MouseSmooth $x $y; Click-Mouse }
|
|
116
337
|
|
|
117
338
|
function Scroll-MouseWheel {
|
|
118
|
-
param([int]$amount = -3)
|
|
119
|
-
|
|
120
|
-
# Scroll in small increments like human
|
|
339
|
+
param([int]$amount = -3)
|
|
121
340
|
$scrolls = [Math]::Abs($amount)
|
|
122
341
|
$direction = if ($amount -lt 0) { -120 } else { 120 }
|
|
123
|
-
|
|
124
342
|
for ($i = 0; $i -lt $scrolls; $i++) {
|
|
125
343
|
[Mouse]::mouse_event([Mouse]::MOUSEEVENTF_WHEEL, 0, 0, $direction, [IntPtr]::Zero)
|
|
126
344
|
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
@@ -128,507 +346,635 @@ function Scroll-MouseWheel {
|
|
|
128
346
|
}
|
|
129
347
|
|
|
130
348
|
function Fidget-Mouse {
|
|
131
|
-
# Small random movements while "thinking"
|
|
132
349
|
$currentPos = [System.Windows.Forms.Cursor]::Position
|
|
133
|
-
$fidgetX = $currentPos.X + (Get-Random -Minimum -30 -Maximum 30)
|
|
134
|
-
$fidgetY = $currentPos.Y + (Get-Random -Minimum -20 -Maximum 20)
|
|
135
|
-
|
|
136
|
-
# Keep on screen
|
|
137
|
-
$fidgetX = [Math]::Max(10, [Math]::Min($script:screenWidth - 10, $fidgetX))
|
|
138
|
-
$fidgetY = [Math]::Max(10, [Math]::Min($script:screenHeight - 10, $fidgetY))
|
|
139
|
-
|
|
350
|
+
$fidgetX = [Math]::Max(10, [Math]::Min($script:screenWidth - 10, $currentPos.X + (Get-Random -Minimum -30 -Maximum 30)))
|
|
351
|
+
$fidgetY = [Math]::Max(10, [Math]::Min($script:screenHeight - 10, $currentPos.Y + (Get-Random -Minimum -20 -Maximum 20)))
|
|
140
352
|
Move-MouseSmooth $fidgetX $fidgetY 8
|
|
141
353
|
}
|
|
142
354
|
|
|
143
355
|
function Get-RandomScreenPosition {
|
|
144
356
|
param([string]$area = "center")
|
|
145
|
-
|
|
146
357
|
switch ($area) {
|
|
147
|
-
"excel-cells" {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
"address-bar" {
|
|
157
|
-
$x = Get-Random -Minimum 200 -Maximum 700
|
|
158
|
-
$y = Get-Random -Minimum 50 -Maximum 80
|
|
159
|
-
}
|
|
160
|
-
"webpage" {
|
|
161
|
-
$x = Get-Random -Minimum 100 -Maximum 1000
|
|
162
|
-
$y = Get-Random -Minimum 200 -Maximum 700
|
|
163
|
-
}
|
|
164
|
-
"chat-list" {
|
|
165
|
-
$x = Get-Random -Minimum 50 -Maximum 280
|
|
166
|
-
$y = Get-Random -Minimum 150 -Maximum 600
|
|
167
|
-
}
|
|
168
|
-
"chat-area" {
|
|
169
|
-
$x = Get-Random -Minimum 350 -Maximum 900
|
|
170
|
-
$y = Get-Random -Minimum 200 -Maximum 650
|
|
171
|
-
}
|
|
172
|
-
default {
|
|
173
|
-
$x = Get-Random -Minimum 200 -Maximum 1000
|
|
174
|
-
$y = Get-Random -Minimum 200 -Maximum 600
|
|
175
|
-
}
|
|
358
|
+
"excel-cells" { $x = Get-Random -Minimum 100 -Maximum 900; $y = Get-Random -Minimum 150 -Maximum 600 }
|
|
359
|
+
"toolbar" { $x = Get-Random -Minimum 50 -Maximum 800; $y = Get-Random -Minimum 30 -Maximum 120 }
|
|
360
|
+
"address-bar" { $x = Get-Random -Minimum 200 -Maximum 700; $y = Get-Random -Minimum 50 -Maximum 80 }
|
|
361
|
+
"webpage" { $x = Get-Random -Minimum 100 -Maximum 1000; $y = Get-Random -Minimum 200 -Maximum 700 }
|
|
362
|
+
"chat-list" { $x = Get-Random -Minimum 50 -Maximum 280; $y = Get-Random -Minimum 150 -Maximum 600 }
|
|
363
|
+
"chat-area" { $x = Get-Random -Minimum 350 -Maximum 900; $y = Get-Random -Minimum 200 -Maximum 650 }
|
|
364
|
+
"sidebar" { $x = Get-Random -Minimum 20 -Maximum 200; $y = Get-Random -Minimum 100 -Maximum 500 }
|
|
365
|
+
default { $x = Get-Random -Minimum 200 -Maximum 1000; $y = Get-Random -Minimum 200 -Maximum 600 }
|
|
176
366
|
}
|
|
177
|
-
|
|
178
367
|
return @{ X = $x; Y = $y }
|
|
179
368
|
}
|
|
180
369
|
|
|
181
|
-
# ==============
|
|
182
|
-
|
|
183
|
-
function Get-RandomDelay {
|
|
184
|
-
param([string]$type = "keystroke")
|
|
185
|
-
switch ($type) {
|
|
186
|
-
"keystroke" { return (Get-Random -Minimum 50 -Maximum 200) }
|
|
187
|
-
"think" { return (Get-Random -Minimum 800 -Maximum 3000) }
|
|
188
|
-
"read" { return (Get-Random -Minimum 3000 -Maximum 12000) }
|
|
189
|
-
"scroll" { return (Get-Random -Minimum 800 -Maximum 2000) }
|
|
190
|
-
"switch" { return (Get-Random -Minimum 500 -Maximum 1500) }
|
|
191
|
-
"message" { return (Get-Random -Minimum 2000 -Maximum 6000) }
|
|
192
|
-
}
|
|
193
|
-
}
|
|
370
|
+
# ============== TYPING FUNCTIONS ==============
|
|
194
371
|
|
|
195
372
|
function Type-WithTypos {
|
|
196
|
-
param([string]$text)
|
|
197
|
-
|
|
198
|
-
$typoChance = 8 # 8% chance of typo per character
|
|
199
|
-
|
|
373
|
+
param([string]$text, [int]$typoChance = 8)
|
|
200
374
|
foreach ($char in $text.ToCharArray()) {
|
|
201
|
-
# Random typo
|
|
202
375
|
if ((Get-Random -Minimum 1 -Maximum 100) -le $typoChance) {
|
|
203
|
-
|
|
204
|
-
$wrongChar = [char]((Get-Random -Minimum 97 -Maximum 122)) # random a-z
|
|
376
|
+
$wrongChar = [char]((Get-Random -Minimum 97 -Maximum 122))
|
|
205
377
|
[System.Windows.Forms.SendKeys]::SendWait($wrongChar)
|
|
206
378
|
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
207
|
-
|
|
208
|
-
# Pause (notice mistake)
|
|
209
379
|
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 500)
|
|
210
|
-
|
|
211
|
-
# Backspace
|
|
212
380
|
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE}")
|
|
213
381
|
Start-Sleep -Milliseconds (Get-Random -Minimum 80 -Maximum 200)
|
|
214
382
|
}
|
|
215
|
-
|
|
216
|
-
# Type correct character
|
|
217
383
|
$escaped = $char
|
|
218
384
|
if ($char -match '[\+\^\%\~\(\)\{\}\[\]]') { $escaped = "{$char}" }
|
|
219
385
|
[System.Windows.Forms.SendKeys]::SendWait($escaped)
|
|
220
|
-
|
|
221
|
-
# Variable delay (sometimes pause mid-word like thinking)
|
|
222
386
|
$delay = Get-Random -Minimum 50 -Maximum 200
|
|
223
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 5) {
|
|
224
|
-
$delay = Get-Random -Minimum 300 -Maximum 800 # Thinking pause
|
|
225
|
-
}
|
|
387
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 5) { $delay = Get-Random -Minimum 300 -Maximum 800 }
|
|
226
388
|
Start-Sleep -Milliseconds $delay
|
|
227
389
|
}
|
|
228
390
|
}
|
|
229
391
|
|
|
230
|
-
function
|
|
231
|
-
param([string]$
|
|
392
|
+
function Type-Number {
|
|
393
|
+
param([string]$num)
|
|
394
|
+
Type-WithTypos $num 5
|
|
395
|
+
}
|
|
232
396
|
|
|
233
|
-
|
|
234
|
-
$taskbarY = $script:screenHeight - 30
|
|
235
|
-
$taskbarX = Get-Random -Minimum 200 -Maximum 800
|
|
236
|
-
Move-MouseSmooth $taskbarX $taskbarY
|
|
237
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 500)
|
|
397
|
+
# ============== TASK SELECTOR (Anti-Pattern) ==============
|
|
238
398
|
|
|
239
|
-
|
|
240
|
-
$
|
|
241
|
-
$currentIdx = [array]::IndexOf($appOrder, $currentApp)
|
|
242
|
-
$targetIdx = [array]::IndexOf($appOrder, $targetApp)
|
|
243
|
-
$tabsNeeded = if ($targetIdx -gt $currentIdx) { $targetIdx - $currentIdx } else { 3 - $currentIdx + $targetIdx }
|
|
244
|
-
$tabsNeeded = [Math]::Max(1, $tabsNeeded)
|
|
399
|
+
function Select-NextTask {
|
|
400
|
+
$catWeights = Get-CategoryWeights
|
|
245
401
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
402
|
+
# Build weighted pool excluding recent tasks
|
|
403
|
+
$pool = @()
|
|
404
|
+
foreach ($task in $script:microTasks) {
|
|
405
|
+
# Skip if in last 10 tasks
|
|
406
|
+
if ($script:taskHistory -contains $task.id) { continue }
|
|
407
|
+
|
|
408
|
+
# Weight by category and task weight
|
|
409
|
+
$catWeight = $catWeights[$task.cat]
|
|
410
|
+
if (-not $catWeight) { $catWeight = 5 }
|
|
411
|
+
$totalWeight = $task.weight * ($catWeight / 10)
|
|
412
|
+
|
|
413
|
+
for ($i = 0; $i -lt [Math]::Ceiling($totalWeight); $i++) {
|
|
414
|
+
$pool += $task
|
|
415
|
+
}
|
|
249
416
|
}
|
|
250
417
|
|
|
251
|
-
|
|
418
|
+
if ($pool.Count -eq 0) {
|
|
419
|
+
# Reset history if pool empty
|
|
420
|
+
$script:taskHistory = @()
|
|
421
|
+
$pool = $script:microTasks
|
|
422
|
+
}
|
|
252
423
|
|
|
253
|
-
|
|
254
|
-
$pos = Get-RandomScreenPosition "center"
|
|
255
|
-
Move-MouseSmooth $pos.X $pos.Y
|
|
256
|
-
}
|
|
424
|
+
$selected = $pool | Get-Random
|
|
257
425
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
$
|
|
261
|
-
|
|
262
|
-
foreach ($app in $appWeights.Keys) {
|
|
263
|
-
$cumulative += $appWeights[$app]
|
|
264
|
-
if ($roll -le $cumulative) {
|
|
265
|
-
if ($app -eq $currentApp) {
|
|
266
|
-
$others = $appWeights.Keys | Where-Object { $_ -ne $currentApp }
|
|
267
|
-
return ($others | Get-Random)
|
|
268
|
-
}
|
|
269
|
-
return $app
|
|
270
|
-
}
|
|
426
|
+
# Update history (keep last 10)
|
|
427
|
+
$script:taskHistory += $selected.id
|
|
428
|
+
if ($script:taskHistory.Count -gt 10) {
|
|
429
|
+
$script:taskHistory = $script:taskHistory[-10..-1]
|
|
271
430
|
}
|
|
272
|
-
|
|
431
|
+
|
|
432
|
+
return $selected
|
|
273
433
|
}
|
|
274
434
|
|
|
275
|
-
# ==============
|
|
435
|
+
# ============== TASK EXECUTORS ==============
|
|
436
|
+
|
|
437
|
+
function Execute-ExcelTask {
|
|
438
|
+
param($task)
|
|
276
439
|
|
|
277
|
-
|
|
278
|
-
$action = Get-Random -Minimum 1 -Maximum 100
|
|
440
|
+
$pos = Get-RandomScreenPosition "excel-cells"
|
|
279
441
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
442
|
+
switch -Wildcard ($task.name) {
|
|
443
|
+
"*SKU*" {
|
|
444
|
+
Move-AndClick $pos.X $pos.Y
|
|
445
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 500)
|
|
446
|
+
Type-WithTypos ($script:skuPool | Get-Random)
|
|
447
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
448
|
+
}
|
|
449
|
+
"*campaign name*" {
|
|
450
|
+
Move-AndClick $pos.X $pos.Y
|
|
451
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 500)
|
|
452
|
+
Type-WithTypos ($script:campaignNames | Get-Random)
|
|
453
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
454
|
+
}
|
|
455
|
+
"*ACOS*" {
|
|
456
|
+
Move-AndClick $pos.X $pos.Y
|
|
457
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
458
|
+
$acos = [math]::Round((Get-Random -Minimum 800 -Maximum 6500) / 100, 2)
|
|
459
|
+
Type-Number "$acos%"
|
|
460
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
461
|
+
}
|
|
462
|
+
"*spend*" {
|
|
463
|
+
Move-AndClick $pos.X $pos.Y
|
|
464
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
465
|
+
$spend = [math]::Round((Get-Random -Minimum 500 -Maximum 50000) / 100, 2)
|
|
466
|
+
Type-Number "`$$spend"
|
|
467
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
468
|
+
}
|
|
469
|
+
"*bid*" {
|
|
470
|
+
Move-AndClick $pos.X $pos.Y
|
|
471
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
472
|
+
$bid = [math]::Round((Get-Random -Minimum 15 -Maximum 350) / 100, 2)
|
|
473
|
+
Type-Number "`$$bid"
|
|
474
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
475
|
+
}
|
|
476
|
+
"*formula*" {
|
|
477
|
+
Move-AndClick $pos.X $pos.Y
|
|
478
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
479
|
+
$formulas = @("=SUM(B2:B50)", "=AVERAGE(C2:C100)", "=B2/C2", "=D2*0.15", "=IF(E2>30,""HIGH"",""OK"")")
|
|
480
|
+
Type-WithTypos ($formulas | Get-Random)
|
|
481
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
482
|
+
}
|
|
483
|
+
"*Scroll*" {
|
|
484
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
485
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
486
|
+
$dir = if ($task.name -match "up") { 3 } else { -3 }
|
|
487
|
+
Scroll-MouseWheel $dir
|
|
488
|
+
}
|
|
489
|
+
"*Click*cell*" {
|
|
490
|
+
Move-AndClick $pos.X $pos.Y
|
|
491
|
+
}
|
|
492
|
+
"*Tab*" {
|
|
493
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
494
|
+
}
|
|
495
|
+
"*Enter*" {
|
|
496
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
497
|
+
}
|
|
498
|
+
"*Save*" {
|
|
499
|
+
Fidget-Mouse
|
|
500
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
501
|
+
[System.Windows.Forms.SendKeys]::SendWait("^s")
|
|
502
|
+
}
|
|
503
|
+
"*Find*" {
|
|
504
|
+
[System.Windows.Forms.SendKeys]::SendWait("^f")
|
|
505
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
506
|
+
Type-WithTypos ($script:skuPool | Get-Random).Substring(0,4)
|
|
507
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2000)
|
|
508
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ESCAPE}")
|
|
509
|
+
}
|
|
510
|
+
"*Copy*" {
|
|
511
|
+
Move-AndClick $pos.X $pos.Y
|
|
512
|
+
[System.Windows.Forms.SendKeys]::SendWait("^c")
|
|
513
|
+
}
|
|
514
|
+
"*Paste*" {
|
|
515
|
+
Move-AndClick $pos.X $pos.Y
|
|
516
|
+
[System.Windows.Forms.SendKeys]::SendWait("^v")
|
|
517
|
+
}
|
|
518
|
+
"*Undo*" {
|
|
519
|
+
[System.Windows.Forms.SendKeys]::SendWait("^z")
|
|
520
|
+
}
|
|
521
|
+
"*worksheet*" {
|
|
522
|
+
$tabX = Get-Random -Minimum 100 -Maximum 400
|
|
523
|
+
Move-AndClick $tabX ($script:screenHeight - 60)
|
|
524
|
+
}
|
|
525
|
+
default {
|
|
526
|
+
# Generic cell interaction
|
|
527
|
+
Move-AndClick $pos.X $pos.Y
|
|
528
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 800)
|
|
529
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 50) {
|
|
530
|
+
$num = Get-Random -Minimum 100 -Maximum 9999
|
|
531
|
+
Type-Number $num.ToString()
|
|
532
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
533
|
+
}
|
|
534
|
+
}
|
|
284
535
|
}
|
|
536
|
+
}
|
|
285
537
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
$pos = Get-RandomScreenPosition "excel-cells"
|
|
289
|
-
Move-AndClick $pos.X $pos.Y
|
|
290
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 500)
|
|
538
|
+
function Execute-ChromeTask {
|
|
539
|
+
param($task)
|
|
291
540
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
$
|
|
541
|
+
switch -Wildcard ($task.name) {
|
|
542
|
+
"*search*" {
|
|
543
|
+
$pos = Get-RandomScreenPosition "address-bar"
|
|
544
|
+
Move-AndClick $pos.X $pos.Y
|
|
545
|
+
[System.Windows.Forms.SendKeys]::SendWait("^a")
|
|
546
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
547
|
+
Type-WithTypos ($script:searchQueries | Get-Random)
|
|
548
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
549
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
295
550
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
$prefix = $skuPrefixes | Get-Random
|
|
306
|
-
$num = Get-Random -Minimum 10000 -Maximum 99999
|
|
307
|
-
Type-WithTypos "$prefix$num"
|
|
308
|
-
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
309
|
-
}
|
|
310
|
-
elseif ($action -le 60) {
|
|
311
|
-
# Type campaign type
|
|
312
|
-
$pos = Get-RandomScreenPosition "excel-cells"
|
|
313
|
-
Move-AndClick $pos.X $pos.Y
|
|
314
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
315
|
-
Type-WithTypos ($campaignTypes | Get-Random)
|
|
316
|
-
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
317
|
-
}
|
|
318
|
-
elseif ($action -le 75) {
|
|
319
|
-
# Scroll with mouse wheel
|
|
320
|
-
$pos = Get-RandomScreenPosition "excel-cells"
|
|
321
|
-
Move-MouseSmooth $pos.X $pos.Y
|
|
322
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
323
|
-
$scrollAmount = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) {
|
|
324
|
-
Get-Random -Minimum -5 -Maximum -2
|
|
325
|
-
} else {
|
|
326
|
-
Get-Random -Minimum 2 -Maximum 5
|
|
551
|
+
"*Load*" {
|
|
552
|
+
$pos = Get-RandomScreenPosition "address-bar"
|
|
553
|
+
Move-AndClick $pos.X $pos.Y
|
|
554
|
+
[System.Windows.Forms.SendKeys]::SendWait("^a")
|
|
555
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
556
|
+
Type-WithTypos ($script:websites | Get-Random)
|
|
557
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
558
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
327
559
|
}
|
|
328
|
-
Scroll
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
560
|
+
"*Scroll*" {
|
|
561
|
+
$pos = Get-RandomScreenPosition "webpage"
|
|
562
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
563
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 800)
|
|
564
|
+
$scrollAmt = Get-Random -Minimum -5 -Maximum -2
|
|
565
|
+
Scroll-MouseWheel $scrollAmt
|
|
566
|
+
}
|
|
567
|
+
"*Click*" {
|
|
568
|
+
$pos = Get-RandomScreenPosition "webpage"
|
|
569
|
+
Move-AndClick $pos.X $pos.Y
|
|
570
|
+
}
|
|
571
|
+
"*new tab*" {
|
|
572
|
+
[System.Windows.Forms.SendKeys]::SendWait("^t")
|
|
573
|
+
}
|
|
574
|
+
"*Close tab*" {
|
|
575
|
+
[System.Windows.Forms.SendKeys]::SendWait("^w")
|
|
576
|
+
}
|
|
577
|
+
"*Switch tab*" {
|
|
578
|
+
[System.Windows.Forms.SendKeys]::SendWait("^{TAB}")
|
|
579
|
+
}
|
|
580
|
+
"*back*" {
|
|
581
|
+
if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) {
|
|
582
|
+
Move-AndClick 45 65
|
|
583
|
+
} else {
|
|
584
|
+
[System.Windows.Forms.SendKeys]::SendWait("%{LEFT}")
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
"*Refresh*" {
|
|
588
|
+
[System.Windows.Forms.SendKeys]::SendWait("{F5}")
|
|
589
|
+
}
|
|
590
|
+
default {
|
|
591
|
+
$pos = Get-RandomScreenPosition "webpage"
|
|
335
592
|
Move-AndClick $pos.X $pos.Y
|
|
336
593
|
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1500)
|
|
337
594
|
}
|
|
338
595
|
}
|
|
339
|
-
elseif ($action -le 92) {
|
|
340
|
-
# Formula with mouse click first
|
|
341
|
-
$pos = Get-RandomScreenPosition "excel-cells"
|
|
342
|
-
Move-AndClick $pos.X $pos.Y
|
|
343
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
344
|
-
$formulas = @("=SUM(B2:B50)", "=AVERAGE(C2:C100)", "=B2/C2", "=D2*0.15")
|
|
345
|
-
Type-WithTypos ($formulas | Get-Random)
|
|
346
|
-
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
# Save (Ctrl+S with mouse movement)
|
|
350
|
-
Fidget-Mouse
|
|
351
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
352
|
-
[System.Windows.Forms.SendKeys]::SendWait("^s")
|
|
353
|
-
Start-Sleep -Milliseconds 500
|
|
354
|
-
}
|
|
355
596
|
}
|
|
356
597
|
|
|
357
|
-
|
|
598
|
+
function Execute-PerpetuaTask {
|
|
599
|
+
param($task)
|
|
358
600
|
|
|
359
|
-
|
|
360
|
-
$
|
|
601
|
+
# Get Perpetua UI positions
|
|
602
|
+
$ui = $script:perpetuaUI
|
|
361
603
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
604
|
+
switch -Wildcard ($task.name) {
|
|
605
|
+
# === GOALS PAGE INTERACTIONS ===
|
|
606
|
+
"*Navigate SP Goals*" {
|
|
607
|
+
# Click sidebar SP item
|
|
608
|
+
Move-AndClick $ui.sidebarSP.x $ui.sidebarSP.y
|
|
609
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
610
|
+
}
|
|
611
|
+
"*Navigate SB Goals*" {
|
|
612
|
+
Move-AndClick $ui.sidebarSB.x $ui.sidebarSB.y
|
|
613
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
614
|
+
}
|
|
615
|
+
"*Navigate SD Goals*" {
|
|
616
|
+
Move-AndClick $ui.sidebarSD.x $ui.sidebarSD.y
|
|
617
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
618
|
+
}
|
|
619
|
+
"*Click goal row*" {
|
|
620
|
+
$x = Get-Random -Minimum $ui.goalRow.x[0] -Maximum $ui.goalRow.x[1]
|
|
621
|
+
$y = Get-Random -Minimum $ui.goalRow.y[0] -Maximum $ui.goalRow.y[1]
|
|
622
|
+
Move-AndClick $x $y
|
|
623
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2500)
|
|
624
|
+
}
|
|
625
|
+
"*Review goal*metric*" {
|
|
626
|
+
$x = Get-Random -Minimum $ui.goalMetrics.x[0] -Maximum $ui.goalMetrics.x[1]
|
|
627
|
+
$y = Get-Random -Minimum $ui.goalMetrics.y[0] -Maximum $ui.goalMetrics.y[1]
|
|
628
|
+
Move-MouseSmooth $x $y
|
|
629
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
630
|
+
Fidget-Mouse
|
|
631
|
+
}
|
|
632
|
+
"*Scroll goals list*" {
|
|
633
|
+
$x = Get-Random -Minimum $ui.goalsList.x[0] -Maximum $ui.goalsList.x[1]
|
|
634
|
+
$y = Get-Random -Minimum $ui.goalsList.y[0] -Maximum $ui.goalsList.y[1]
|
|
635
|
+
Move-MouseSmooth $x $y
|
|
636
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
637
|
+
$dir = if ($task.name -match "up") { 3 } else { -3 }
|
|
638
|
+
Scroll-MouseWheel $dir
|
|
639
|
+
}
|
|
640
|
+
"*Click goal tabs*" {
|
|
641
|
+
$x = Get-Random -Minimum $ui.goalTabs.x[0] -Maximum $ui.goalTabs.x[1]
|
|
642
|
+
$y = Get-Random -Minimum $ui.goalTabs.y[0] -Maximum $ui.goalTabs.y[1]
|
|
643
|
+
Move-AndClick $x $y
|
|
644
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 3000)
|
|
645
|
+
}
|
|
646
|
+
"*Search goal*" {
|
|
647
|
+
Move-AndClick $ui.searchBox.x $ui.searchBox.y
|
|
648
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
649
|
+
[System.Windows.Forms.SendKeys]::SendWait("^a")
|
|
650
|
+
Start-Sleep -Milliseconds 200
|
|
651
|
+
$goalName = $script:campaignNames | Get-Random
|
|
652
|
+
$searchTerm = $goalName.Split("_")[0..1] -join "_"
|
|
653
|
+
Type-WithTypos $searchTerm
|
|
654
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 3000)
|
|
655
|
+
}
|
|
656
|
+
"*Filter goals*" {
|
|
657
|
+
# Click filter dropdown area
|
|
658
|
+
$x = Get-Random -Minimum 300 -Maximum 500
|
|
659
|
+
Move-AndClick $x 120
|
|
660
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
661
|
+
# Click option
|
|
662
|
+
$y = if ($task.name -match "Enabled") { 160 } else { 190 }
|
|
663
|
+
Move-AndClick ($x + 20) $y
|
|
664
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2000)
|
|
665
|
+
}
|
|
666
|
+
"*Sort by*column*" {
|
|
667
|
+
# Click column header
|
|
668
|
+
$x = if ($task.name -match "ACOS") { 900 } else { 800 }
|
|
669
|
+
Move-AndClick $x 175
|
|
670
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2000)
|
|
671
|
+
}
|
|
672
|
+
"*Change date range*" {
|
|
673
|
+
Move-AndClick $ui.dateRangePicker.x $ui.dateRangePicker.y
|
|
674
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
675
|
+
# Click a preset option
|
|
676
|
+
$y = if ($task.name -match "7d") { 200 } else { 230 }
|
|
677
|
+
Move-AndClick ($ui.dateRangePicker.x - 50) $y
|
|
678
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 3000)
|
|
679
|
+
}
|
|
680
|
+
"*New Goal button*" {
|
|
681
|
+
Move-AndClick $ui.newGoalBtn.x $ui.newGoalBtn.y
|
|
682
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
683
|
+
# Press Escape to close without creating
|
|
684
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ESCAPE}")
|
|
685
|
+
Start-Sleep -Milliseconds 500
|
|
686
|
+
}
|
|
687
|
+
"*Close goal detail*" {
|
|
688
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ESCAPE}")
|
|
689
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
690
|
+
}
|
|
367
691
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
386
|
-
Type-WithTypos ($websites | Get-Random)
|
|
387
|
-
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
388
|
-
Start-Sleep -Milliseconds (Get-RandomDelay "read")
|
|
389
|
-
}
|
|
390
|
-
elseif ($action -le 70) {
|
|
391
|
-
# Scroll with mouse wheel
|
|
392
|
-
$pos = Get-RandomScreenPosition "webpage"
|
|
393
|
-
Move-MouseSmooth $pos.X $pos.Y
|
|
394
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 800)
|
|
395
|
-
|
|
396
|
-
$scrollSessions = Get-Random -Minimum 2 -Maximum 5
|
|
397
|
-
for ($i = 0; $i -lt $scrollSessions; $i++) {
|
|
692
|
+
# === STREAMS PAGE INTERACTIONS ===
|
|
693
|
+
"*Navigate SP Streams*" {
|
|
694
|
+
# Click Streams in sidebar or tab
|
|
695
|
+
$x = Get-Random -Minimum $ui.sidebar.x[0] -Maximum $ui.sidebar.x[1]
|
|
696
|
+
Move-AndClick $x 320
|
|
697
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
698
|
+
}
|
|
699
|
+
"*Click stream row*" {
|
|
700
|
+
$x = Get-Random -Minimum $ui.streamRow.x[0] -Maximum $ui.streamRow.x[1]
|
|
701
|
+
$y = Get-Random -Minimum $ui.streamRow.y[0] -Maximum $ui.streamRow.y[1]
|
|
702
|
+
Move-AndClick $x $y
|
|
703
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2500)
|
|
704
|
+
}
|
|
705
|
+
"*Scroll streams list*" {
|
|
706
|
+
$x = Get-Random -Minimum $ui.streamsList.x[0] -Maximum $ui.streamsList.x[1]
|
|
707
|
+
$y = Get-Random -Minimum $ui.streamsList.y[0] -Maximum $ui.streamsList.y[1]
|
|
708
|
+
Move-MouseSmooth $x $y
|
|
398
709
|
Scroll-MouseWheel (Get-Random -Minimum -4 -Maximum -2)
|
|
399
|
-
Start-Sleep -Milliseconds (Get-RandomDelay "scroll")
|
|
400
|
-
|
|
401
|
-
# Sometimes fidget while reading
|
|
402
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 30) {
|
|
403
|
-
Fidget-Mouse
|
|
404
|
-
}
|
|
405
710
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
711
|
+
"*View stream bid*" {
|
|
712
|
+
$x = Get-Random -Minimum 600 -Maximum 900
|
|
713
|
+
$y = Get-Random -Minimum 250 -Maximum 400
|
|
714
|
+
Move-MouseSmooth $x $y
|
|
715
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
716
|
+
}
|
|
717
|
+
"*Filter streams*" {
|
|
718
|
+
$x = Get-Random -Minimum $ui.streamFilters.x[0] -Maximum $ui.streamFilters.x[1]
|
|
719
|
+
$y = Get-Random -Minimum $ui.streamFilters.y[0] -Maximum $ui.streamFilters.y[1]
|
|
720
|
+
Move-AndClick $x $y
|
|
721
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2000)
|
|
722
|
+
}
|
|
723
|
+
"*stream*trend*" {
|
|
724
|
+
# Hover over graph area
|
|
725
|
+
$x = Get-Random -Minimum 700 -Maximum 1200
|
|
726
|
+
$y = Get-Random -Minimum 300 -Maximum 450
|
|
727
|
+
Move-MouseSmooth $x $y
|
|
728
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 4000)
|
|
419
729
|
Fidget-Mouse
|
|
420
|
-
[System.Windows.Forms.SendKeys]::SendWait("%{LEFT}")
|
|
421
730
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
731
|
+
"*Expand stream*" {
|
|
732
|
+
$x = Get-Random -Minimum 250 -Maximum 300
|
|
733
|
+
$y = Get-Random -Minimum 220 -Maximum 500
|
|
734
|
+
Move-AndClick $x $y
|
|
735
|
+
}
|
|
736
|
+
"*Collapse stream*" {
|
|
737
|
+
$x = Get-Random -Minimum 250 -Maximum 300
|
|
738
|
+
$y = Get-Random -Minimum 220 -Maximum 400
|
|
739
|
+
Move-AndClick $x $y
|
|
740
|
+
}
|
|
741
|
+
"*Sort streams*" {
|
|
742
|
+
$x = Get-Random -Minimum 700 -Maximum 900
|
|
743
|
+
Move-AndClick $x 175
|
|
744
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2000)
|
|
745
|
+
}
|
|
746
|
+
"*stream automation*" {
|
|
747
|
+
# Click automation toggle area
|
|
748
|
+
$x = Get-Random -Minimum 1100 -Maximum 1300
|
|
749
|
+
$y = Get-Random -Minimum 250 -Maximum 450
|
|
750
|
+
Move-MouseSmooth $x $y
|
|
751
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 3000)
|
|
752
|
+
}
|
|
753
|
+
"*Navigate Analytics*" {
|
|
754
|
+
Move-AndClick $ui.sidebarAnalytics.x $ui.sidebarAnalytics.y
|
|
755
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
# === GENERAL PERPETUA INTERACTIONS ===
|
|
759
|
+
"*sidebar nav*" {
|
|
760
|
+
$x = Get-Random -Minimum $ui.sidebar.x[0] -Maximum $ui.sidebar.x[1]
|
|
761
|
+
$y = Get-Random -Minimum $ui.sidebar.y[0] -Maximum $ui.sidebar.y[1]
|
|
762
|
+
Move-AndClick $x $y
|
|
763
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 3000)
|
|
764
|
+
}
|
|
765
|
+
"*Hover sidebar*" {
|
|
766
|
+
$x = Get-Random -Minimum 20 -Maximum 60
|
|
767
|
+
$y = Get-Random -Minimum 150 -Maximum 500
|
|
768
|
+
Move-MouseSmooth $x $y
|
|
769
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 800 -Maximum 2000)
|
|
770
|
+
}
|
|
771
|
+
"*account dropdown*" {
|
|
772
|
+
Move-AndClick $ui.accountDropdown.x $ui.accountDropdown.y
|
|
773
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
774
|
+
# Click elsewhere to close
|
|
775
|
+
Move-AndClick 800 400
|
|
776
|
+
}
|
|
777
|
+
"*notifications bell*" {
|
|
778
|
+
Move-AndClick ($ui.accountDropdown.x - 80) $ui.accountDropdown.y
|
|
779
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2500)
|
|
780
|
+
# Click elsewhere to close
|
|
781
|
+
Move-AndClick 800 400
|
|
782
|
+
}
|
|
783
|
+
"*Refresh current*" {
|
|
784
|
+
[System.Windows.Forms.SendKeys]::SendWait("{F5}")
|
|
785
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 4000)
|
|
786
|
+
}
|
|
787
|
+
"*breadcrumb*" {
|
|
788
|
+
$x = Get-Random -Minimum 220 -Maximum 400
|
|
789
|
+
Move-AndClick $x 80
|
|
790
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 3000)
|
|
791
|
+
}
|
|
792
|
+
"*Scroll page randomly*" {
|
|
793
|
+
$x = Get-Random -Minimum 400 -Maximum 1200
|
|
794
|
+
$y = Get-Random -Minimum 300 -Maximum 600
|
|
795
|
+
Move-MouseSmooth $x $y
|
|
796
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 800)
|
|
797
|
+
$dir = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) { -3 } else { 3 }
|
|
798
|
+
Scroll-MouseWheel $dir
|
|
799
|
+
}
|
|
800
|
+
"*idle on metrics*" {
|
|
801
|
+
$x = Get-Random -Minimum 600 -Maximum 1100
|
|
802
|
+
$y = Get-Random -Minimum 200 -Maximum 500
|
|
803
|
+
Move-MouseSmooth $x $y
|
|
804
|
+
# Just hover and look
|
|
805
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 3000 -Maximum 8000)
|
|
806
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 40) { Fidget-Mouse }
|
|
807
|
+
}
|
|
808
|
+
default {
|
|
809
|
+
# Generic Perpetua interaction
|
|
810
|
+
$x = Get-Random -Minimum 300 -Maximum 1200
|
|
811
|
+
$y = Get-Random -Minimum 200 -Maximum 600
|
|
812
|
+
Move-MouseSmooth $x $y
|
|
813
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1500)
|
|
814
|
+
}
|
|
429
815
|
}
|
|
430
816
|
}
|
|
431
817
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
function Do-TeamsAction {
|
|
435
|
-
$action = Get-Random -Minimum 1 -Maximum 100
|
|
436
|
-
|
|
437
|
-
if ($action -le 60) {
|
|
438
|
-
# Click on chats and read
|
|
439
|
-
$messagesToCheck = Get-Random -Minimum 1 -Maximum 4
|
|
818
|
+
function Execute-TeamsTask {
|
|
819
|
+
param($task)
|
|
440
820
|
|
|
441
|
-
|
|
442
|
-
|
|
821
|
+
switch -Wildcard ($task.name) {
|
|
822
|
+
"*chat*" {
|
|
443
823
|
$pos = Get-RandomScreenPosition "chat-list"
|
|
444
824
|
Move-AndClick $pos.X $pos.Y
|
|
445
825
|
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
446
|
-
|
|
447
|
-
# Move to chat area and read
|
|
448
826
|
$chatPos = Get-RandomScreenPosition "chat-area"
|
|
449
827
|
Move-MouseSmooth $chatPos.X $chatPos.Y
|
|
450
|
-
Start-Sleep -Milliseconds (Get-RandomDelay "message")
|
|
451
|
-
|
|
452
|
-
# Sometimes scroll up in chat
|
|
453
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 40) {
|
|
454
|
-
Scroll-MouseWheel (Get-Random -Minimum 2 -Maximum 5)
|
|
455
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 2000)
|
|
456
|
-
Scroll-MouseWheel (Get-Random -Minimum -3 -Maximum -1)
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
# Fidget while reading
|
|
460
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 50) {
|
|
461
|
-
Fidget-Mouse
|
|
462
|
-
}
|
|
463
828
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
829
|
+
"*Read*" {
|
|
830
|
+
$pos = Get-RandomScreenPosition "chat-area"
|
|
831
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
832
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
833
|
+
}
|
|
834
|
+
"*Scroll*" {
|
|
835
|
+
$pos = if ($task.name -match "channel") { Get-RandomScreenPosition "sidebar" } else { Get-RandomScreenPosition "chat-area" }
|
|
836
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
837
|
+
Scroll-MouseWheel (Get-Random -Minimum -3 -Maximum 3)
|
|
838
|
+
}
|
|
839
|
+
"*activity*" {
|
|
840
|
+
$pos = Get-RandomScreenPosition "sidebar"
|
|
841
|
+
Move-AndClick $pos.X 100
|
|
842
|
+
}
|
|
843
|
+
"*React*" {
|
|
844
|
+
$pos = Get-RandomScreenPosition "chat-area"
|
|
845
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
846
|
+
# Hover for reaction
|
|
474
847
|
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1000)
|
|
475
848
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
481
|
-
Fidget-Mouse
|
|
849
|
+
default {
|
|
850
|
+
$pos = Get-RandomScreenPosition "chat-list"
|
|
851
|
+
Move-AndClick $pos.X $pos.Y
|
|
852
|
+
}
|
|
482
853
|
}
|
|
483
854
|
}
|
|
484
855
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
function Do-BulkBidOptimization {
|
|
488
|
-
$rows = Get-Random -Minimum 12 -Maximum 30
|
|
489
|
-
|
|
490
|
-
# Start at top
|
|
491
|
-
$pos = Get-RandomScreenPosition "excel-cells"
|
|
492
|
-
Move-AndClick $pos.X 180
|
|
493
|
-
Start-Sleep -Milliseconds 500
|
|
494
|
-
|
|
495
|
-
for ($r = 0; $r -lt $rows; $r++) {
|
|
496
|
-
# Click on bid cell
|
|
497
|
-
$cellX = Get-Random -Minimum 400 -Maximum 500
|
|
498
|
-
$cellY = 180 + ($r * 20)
|
|
499
|
-
if ($cellY -gt 600) {
|
|
500
|
-
Scroll-MouseWheel -3
|
|
501
|
-
Start-Sleep -Milliseconds 500
|
|
502
|
-
$cellY = 300
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
Move-AndClick $cellX $cellY
|
|
506
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1500)
|
|
856
|
+
function Execute-HumanTask {
|
|
857
|
+
param($task)
|
|
507
858
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
859
|
+
switch -Wildcard ($task.name) {
|
|
860
|
+
"*Pause*think*" {
|
|
861
|
+
# Just wait, maybe small fidget
|
|
862
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 30) { Fidget-Mouse }
|
|
512
863
|
}
|
|
513
|
-
|
|
514
|
-
# Occasional fidget
|
|
515
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 20) {
|
|
864
|
+
"*fidget*" {
|
|
516
865
|
Fidget-Mouse
|
|
517
866
|
}
|
|
867
|
+
"*Hesitation*" {
|
|
868
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 2000)
|
|
869
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 40) { Fidget-Mouse }
|
|
870
|
+
}
|
|
871
|
+
"*Re-read*" {
|
|
872
|
+
$pos = Get-RandomScreenPosition "center"
|
|
873
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
874
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 3000)
|
|
875
|
+
}
|
|
876
|
+
"*break*" {
|
|
877
|
+
# Longer pause with occasional fidget
|
|
878
|
+
$breakTime = Get-Random -Minimum 15 -Maximum 45
|
|
879
|
+
for ($i = 0; $i -lt $breakTime; $i += 5) {
|
|
880
|
+
Start-Sleep -Seconds 5
|
|
881
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 20) { Fidget-Mouse }
|
|
882
|
+
}
|
|
883
|
+
}
|
|
518
884
|
}
|
|
519
|
-
|
|
520
|
-
[System.Windows.Forms.SendKeys]::SendWait("^s")
|
|
521
|
-
Start-Sleep -Milliseconds 1000
|
|
522
885
|
}
|
|
523
886
|
|
|
524
|
-
|
|
525
|
-
$terms = Get-Random -Minimum 15 -Maximum 35
|
|
887
|
+
# ============== APP SWITCHING ==============
|
|
526
888
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
Start-Sleep -Milliseconds 500
|
|
530
|
-
|
|
531
|
-
for ($t = 0; $t -lt $terms; $t++) {
|
|
532
|
-
# Scroll and click through rows
|
|
533
|
-
$cellY = 180 + (($t % 15) * 22)
|
|
534
|
-
if ($t % 15 -eq 0 -and $t -gt 0) {
|
|
535
|
-
Scroll-MouseWheel -4
|
|
536
|
-
Start-Sleep -Milliseconds 800
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
$cellX = Get-Random -Minimum 100 -Maximum 300
|
|
540
|
-
Move-AndClick $cellX $cellY
|
|
541
|
-
Start-Sleep -Milliseconds (Get-Random -Minimum 600 -Maximum 2000)
|
|
542
|
-
|
|
543
|
-
# Mark as negative
|
|
544
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 20) {
|
|
545
|
-
$endCellX = Get-Random -Minimum 700 -Maximum 850
|
|
546
|
-
Move-AndClick $endCellX $cellY
|
|
547
|
-
Start-Sleep -Milliseconds 300
|
|
548
|
-
Type-WithTypos "NEGATIVE"
|
|
549
|
-
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
550
|
-
Start-Sleep -Milliseconds 500
|
|
551
|
-
}
|
|
889
|
+
function Switch-ToApp {
|
|
890
|
+
param([string]$targetApp)
|
|
552
891
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
892
|
+
if ($targetApp -eq $script:lastApp) { return }
|
|
893
|
+
|
|
894
|
+
# Move to taskbar area
|
|
895
|
+
$taskbarY = $script:screenHeight - 30
|
|
896
|
+
$taskbarX = Get-Random -Minimum 200 -Maximum 800
|
|
897
|
+
Move-MouseSmooth $taskbarX $taskbarY
|
|
898
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 500)
|
|
899
|
+
|
|
900
|
+
# Alt+Tab cycles
|
|
901
|
+
$tabCount = Get-Random -Minimum 1 -Maximum 3
|
|
902
|
+
for ($i = 0; $i -lt $tabCount; $i++) {
|
|
903
|
+
[System.Windows.Forms.SendKeys]::SendWait("%{TAB}")
|
|
904
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
556
905
|
}
|
|
557
906
|
|
|
558
|
-
|
|
907
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 1500)
|
|
908
|
+
$script:lastApp = $targetApp
|
|
909
|
+
|
|
910
|
+
# Move to app area
|
|
911
|
+
$pos = Get-RandomScreenPosition "center"
|
|
912
|
+
Move-MouseSmooth $pos.X $pos.Y
|
|
559
913
|
}
|
|
560
914
|
|
|
561
915
|
# ============== MAIN TRACKER ==============
|
|
562
916
|
|
|
563
917
|
function Start-Tracking {
|
|
564
|
-
$currentApp = "excel"
|
|
565
918
|
$totalActions = 0
|
|
566
|
-
$
|
|
919
|
+
$script:sessionStart = Get-Date
|
|
567
920
|
|
|
568
921
|
Write-Host "[TRACKING] Started at $(Get-Date -Format 'HH:mm:ss')" -ForegroundColor Green
|
|
569
|
-
Write-Host "[INFO]
|
|
922
|
+
Write-Host "[INFO] v3.1 - 130 micro-tasks, Perpetua UI, anti-pattern" -ForegroundColor Cyan
|
|
923
|
+
Write-Host "[INFO] Click Excel window now. Ctrl+C to stop." -ForegroundColor Yellow
|
|
570
924
|
Start-Sleep -Seconds 3
|
|
571
925
|
|
|
572
|
-
# Initial mouse position
|
|
573
926
|
$pos = Get-RandomScreenPosition "excel-cells"
|
|
574
927
|
Move-MouseSmooth $pos.X $pos.Y
|
|
928
|
+
$script:lastApp = "excel"
|
|
575
929
|
|
|
576
930
|
try {
|
|
577
931
|
while ($true) {
|
|
578
|
-
|
|
932
|
+
# Select next task (anti-pattern)
|
|
933
|
+
$task = Select-NextTask
|
|
579
934
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
Switch-ToApp $
|
|
583
|
-
$currentApp = $nextApp
|
|
935
|
+
# Maybe switch app
|
|
936
|
+
if ($task.cat -ne $script:lastApp -and $task.cat -ne "human") {
|
|
937
|
+
Switch-ToApp $task.cat
|
|
584
938
|
}
|
|
585
939
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
elseif ($currentApp -eq "excel") {
|
|
594
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le 12) {
|
|
595
|
-
$tasks = @("Do-BulkBidOptimization", "Do-SearchTermReview")
|
|
596
|
-
& ($tasks | Get-Random)
|
|
597
|
-
$totalActions += 20
|
|
598
|
-
}
|
|
599
|
-
else {
|
|
600
|
-
$burstSize = Get-Random -Minimum 3 -Maximum 8
|
|
601
|
-
for ($i = 0; $i -lt $burstSize; $i++) {
|
|
602
|
-
Do-ExcelAction
|
|
603
|
-
$totalActions++
|
|
604
|
-
Start-Sleep -Milliseconds (Get-RandomDelay "think")
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
else {
|
|
609
|
-
$burstSize = Get-Random -Minimum 3 -Maximum 8
|
|
610
|
-
for ($i = 0; $i -lt $burstSize; $i++) {
|
|
611
|
-
Do-ChromeBrowse
|
|
612
|
-
$totalActions++
|
|
613
|
-
Start-Sleep -Milliseconds (Get-RandomDelay "think")
|
|
614
|
-
}
|
|
940
|
+
# Execute task
|
|
941
|
+
switch ($task.cat) {
|
|
942
|
+
"excel" { Execute-ExcelTask $task }
|
|
943
|
+
"perpetua" { Execute-PerpetuaTask $task }
|
|
944
|
+
"chrome" { Execute-ChromeTask $task }
|
|
945
|
+
"teams" { Execute-TeamsTask $task }
|
|
946
|
+
"human" { Execute-HumanTask $task }
|
|
615
947
|
}
|
|
616
948
|
|
|
617
|
-
|
|
618
|
-
|
|
949
|
+
$totalActions++
|
|
950
|
+
|
|
951
|
+
# Task duration (from task spec)
|
|
952
|
+
$minDur = $task.dur[0]
|
|
953
|
+
$maxDur = $task.dur[1]
|
|
954
|
+
$taskDuration = Get-Random -Minimum $minDur -Maximum $maxDur
|
|
955
|
+
|
|
956
|
+
# Execute duration with fidgets
|
|
619
957
|
$elapsed = 0
|
|
620
|
-
while ($elapsed -lt $
|
|
958
|
+
while ($elapsed -lt $taskDuration) {
|
|
959
|
+
$sleepTime = [Math]::Min(5, $taskDuration - $elapsed)
|
|
960
|
+
Start-Sleep -Seconds $sleepTime
|
|
961
|
+
$elapsed += $sleepTime
|
|
962
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 15) { Fidget-Mouse }
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
# Gap between tasks (5-29 sec)
|
|
966
|
+
$gap = Get-Random -Minimum 5 -Maximum 29
|
|
967
|
+
$gapElapsed = 0
|
|
968
|
+
while ($gapElapsed -lt $gap) {
|
|
621
969
|
Start-Sleep -Seconds 5
|
|
622
|
-
$
|
|
623
|
-
if ((Get-Random -Minimum 1 -Maximum 100) -le
|
|
624
|
-
Fidget-Mouse
|
|
625
|
-
}
|
|
970
|
+
$gapElapsed += 5
|
|
971
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 20) { Fidget-Mouse }
|
|
626
972
|
}
|
|
627
973
|
}
|
|
628
974
|
}
|
|
629
975
|
finally {
|
|
630
|
-
$
|
|
631
|
-
Write-Host "`n[STOPPED] Runtime: $
|
|
976
|
+
$runTime = [math]::Round(((Get-Date) - $script:sessionStart).TotalMinutes, 1)
|
|
977
|
+
Write-Host "`n[STOPPED] Runtime: $runTime min | Actions: $totalActions" -ForegroundColor Yellow
|
|
632
978
|
}
|
|
633
979
|
}
|
|
634
980
|
|
|
@@ -636,34 +982,25 @@ function Start-Tracking {
|
|
|
636
982
|
|
|
637
983
|
Clear-Host
|
|
638
984
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
639
|
-
Write-Host " Amazon Advertising Spend Tracker
|
|
985
|
+
Write-Host " Amazon Advertising Spend Tracker v3.1" -ForegroundColor Cyan
|
|
640
986
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
641
987
|
Write-Host ""
|
|
988
|
+
Write-Host "130 micro-tasks | Perpetua UI precision | Anti-pattern"
|
|
989
|
+
Write-Host "Time-of-day awareness | Human behaviors"
|
|
990
|
+
Write-Host ""
|
|
642
991
|
Write-Host "Commands:"
|
|
643
|
-
Write-Host " go - Start tracking
|
|
644
|
-
Write-Host " exit - Close
|
|
992
|
+
Write-Host " go - Start tracking"
|
|
993
|
+
Write-Host " exit - Close"
|
|
645
994
|
Write-Host ""
|
|
646
|
-
Write-Host "Stop tracking: Press Ctrl+C"
|
|
647
995
|
Write-Host "Setup: Open Excel, Chrome, Teams first"
|
|
648
996
|
Write-Host "----------------------------------------"
|
|
649
997
|
Write-Host ""
|
|
650
998
|
|
|
651
999
|
while ($true) {
|
|
652
1000
|
$cmd = Read-Host "tracker"
|
|
653
|
-
|
|
654
1001
|
switch ($cmd.ToLower().Trim()) {
|
|
655
|
-
"go" {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
659
|
-
"exit" {
|
|
660
|
-
Write-Host "[INFO] Closing..." -ForegroundColor Yellow
|
|
661
|
-
exit
|
|
662
|
-
}
|
|
663
|
-
default {
|
|
664
|
-
if ($cmd -ne "") {
|
|
665
|
-
Write-Host "[ERROR] Unknown: $cmd (use: go | exit)" -ForegroundColor Red
|
|
666
|
-
}
|
|
667
|
-
}
|
|
1002
|
+
"go" { Start-Tracking; Write-Host "" }
|
|
1003
|
+
"exit" { Write-Host "[INFO] Closing..." -ForegroundColor Yellow; exit }
|
|
1004
|
+
default { if ($cmd -ne "") { Write-Host "[ERROR] Unknown: $cmd (use: go | exit)" -ForegroundColor Red } }
|
|
668
1005
|
}
|
|
669
1006
|
}
|