feature/gemini-web-provider #1
|
|
@ -132,10 +132,15 @@ func (p *PlaywrightProvider) Generate(ctx context.Context, model string, message
|
|||
}); err != nil {
|
||||
return fmt.Errorf("failed to navigate: %w", err)
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
// 3. 檢查登入狀態
|
||||
// 3. 等待頁面完全載入(project-golem 策略)
|
||||
fmt.Println("[GeminiWeb] Waiting for page to be ready...")
|
||||
if err := p.waitForPageReady(); err != nil {
|
||||
fmt.Printf("[GeminiWeb] Warning: %v\n", err)
|
||||
}
|
||||
|
||||
// 4. 檢查登入狀態
|
||||
fmt.Println("[GeminiWeb] Checking login status...")
|
||||
loggedIn := p.isLoggedIn()
|
||||
if !loggedIn {
|
||||
|
|
@ -151,11 +156,6 @@ func (p *PlaywrightProvider) Generate(ctx context.Context, model string, message
|
|||
fmt.Println("[GeminiWeb] Logged in")
|
||||
}
|
||||
|
||||
// 4. 等待頁面就緒
|
||||
if err := p.waitForReady(); err != nil {
|
||||
fmt.Printf("[GeminiWeb] Warning: %v\n", err)
|
||||
}
|
||||
|
||||
// 5. 建構提示詞
|
||||
prompt := buildPromptFromMessagesPlaywright(messages)
|
||||
fmt.Printf("[GeminiWeb] Typing prompt (%d chars)...\n", len(prompt))
|
||||
|
|
@ -201,6 +201,58 @@ func (p *PlaywrightProvider) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// waitForPageReady 等待頁面完全就緒(project-golem 策略)
|
||||
func (p *PlaywrightProvider) waitForPageReady() error {
|
||||
fmt.Println("[GeminiWeb] Checking for ready state...")
|
||||
|
||||
// 1. 等待停止按鈕消失(如果存在)
|
||||
_, _ = p.page.WaitForSelector("button[aria-label*='Stop'], button[aria-label*='停止']", playwright.PageWaitForSelectorOptions{
|
||||
State: playwright.WaitForSelectorStateDetached,
|
||||
Timeout: playwright.Float(5000),
|
||||
})
|
||||
|
||||
// 2. 等待輸入框出現(關鍵!)
|
||||
inputSelectors := []string{
|
||||
".ProseMirror",
|
||||
"rich-textarea",
|
||||
"div[role='textbox']",
|
||||
"div[contenteditable='true']",
|
||||
"textarea",
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for _, sel := range inputSelectors {
|
||||
fmt.Printf(" Checking for: %s\n", sel)
|
||||
locator := p.page.Locator(sel)
|
||||
if err := locator.WaitFor(playwright.LocatorWaitForOptions{
|
||||
Timeout: playwright.Float(10000),
|
||||
State: playwright.WaitForSelectorStateVisible,
|
||||
}); err == nil {
|
||||
fmt.Printf(" ✓ Input field found: %s\n", sel)
|
||||
return nil
|
||||
} else {
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果都找不到,給頁面更多時間
|
||||
fmt.Println("[GeminiWeb] Input not found immediately, waiting longer...")
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
for _, sel := range inputSelectors {
|
||||
locator := p.page.Locator(sel)
|
||||
if err := locator.WaitFor(playwright.LocatorWaitForOptions{
|
||||
Timeout: playwright.Float(5000),
|
||||
State: playwright.WaitForSelectorStateVisible,
|
||||
}); err == nil {
|
||||
fmt.Printf(" ✓ Input field found after wait: %s\n", sel)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("input field not ready: %w", lastErr)
|
||||
}
|
||||
|
||||
// isLoggedIn 檢查是否已登入
|
||||
func (p *PlaywrightProvider) isLoggedIn() bool {
|
||||
// 嘗試找輸入框(登入狀態的主要特徵)
|
||||
|
|
@ -213,29 +265,14 @@ func (p *PlaywrightProvider) isLoggedIn() bool {
|
|||
}
|
||||
|
||||
for _, sel := range selectors {
|
||||
if _, err := p.page.WaitForSelector(sel, playwright.PageWaitForSelectorOptions{
|
||||
Timeout: playwright.Float(3000),
|
||||
}); err == nil {
|
||||
locator := p.page.Locator(sel)
|
||||
if count, _ := locator.Count(); count > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// waitForReady 等待頁面就緒
|
||||
func (p *PlaywrightProvider) waitForReady() error {
|
||||
fmt.Println("[GeminiWeb] Checking if page is ready...")
|
||||
|
||||
// 等待停止按鈕消失(如果存在)
|
||||
_, _ = p.page.WaitForSelector("button[aria-label*='Stop']", playwright.PageWaitForSelectorOptions{
|
||||
State: playwright.WaitForSelectorStateDetached,
|
||||
Timeout: playwright.Float(5000),
|
||||
})
|
||||
|
||||
fmt.Println("[GeminiWeb] Page is ready")
|
||||
return nil
|
||||
}
|
||||
|
||||
// typeInput 輸入文字(使用 Playwright 的 Auto-wait)
|
||||
func (p *PlaywrightProvider) typeInput(text string) error {
|
||||
fmt.Println("[GeminiWeb] Looking for input field...")
|
||||
|
|
|
|||
Loading…
Reference in New Issue