Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
48 changes: 33 additions & 15 deletions internal/xhs/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ func (p *rodPage) PublishOnlySelf(ctx context.Context, request PublishRequest) e
return err
}
if !clicked {
clicked, err = p.clickByText("button", "^发布$")
clicked, err = p.clickByText("button, xhs-publish-btn", "^发布$")
if err != nil {
return err
}
Expand All @@ -401,17 +401,14 @@ func (p *rodPage) clickOnlySelfPublishButton() (bool, error) {
const style = window.getComputedStyle(node);
return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
};
const fire = (node, type) => node.dispatchEvent(new MouseEvent(type, { bubbles: true, cancelable: true, view: window, button: 0 }));
const nodes = Array.from(document.querySelectorAll('xhs-publish-btn[is-publish="true"][submit-disabled="false"]'));
for (const node of nodes) {
if (!isVisible(node)) continue;
const submitText = (node.getAttribute('submit-text') || '').replace(/\s+/g, ' ').trim();
const text = (node.innerText || node.textContent || '').replace(/\s+/g, ' ').trim();
if (submitText !== '发布' && text !== '发布') continue;
node.scrollIntoView({ block: 'center' });
fire(node, 'mousedown');
fire(node, 'mouseup');
node.click();
node.scrollIntoView({ block: 'center', behavior: 'instant' });
node.dispatchEvent(new CustomEvent('publish', { bubbles: true, cancelable: true, composed: true }));
return true;
}
return false;
Expand Down Expand Up @@ -1771,7 +1768,34 @@ func (p *rodPage) setOnlySelfVisible() error {
return nil
}

func (p *rodPage) isPublishEditorActive() bool {
active := false
_ = rodTry(func() {
active = p.page.MustEval(`() => {
const isVisible = (node) => {
if (!node) return false;
const rect = node.getBoundingClientRect();
const style = window.getComputedStyle(node);
return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
};
const hasTitleInput = Array.from(document.querySelectorAll('input[placeholder="填写标题会有更多赞哦"], input[placeholder*="填写标题"], input[placeholder*="标题"]')).some(isVisible);
const hasContentEditor = Array.from(document.querySelectorAll('div.tiptap.ProseMirror[contenteditable="true"], div.ProseMirror[contenteditable="true"], div[contenteditable="true"][role="textbox"]')).some(isVisible);
const hasPublishButton = Array.from(document.querySelectorAll('button, xhs-publish-btn[is-publish="true"]')).some((el) => {
if (!isVisible(el)) return false;
if (el.getAttribute('submit-disabled') === 'true' || el.disabled === true) return false;
const text = ((el.getAttribute('submit-text') || '') + ' ' + (el.innerText || el.textContent || '')).replace(/\s+/g, ' ').trim();
return /发布/.test(text);
});
return hasTitleInput || hasContentEditor || hasPublishButton;
}`).Bool()
})
return active
}

func (p *rodPage) isPublishSuccessState() bool {
if p.isPublishEditorActive() {
return false
}
success := false
_ = rodTry(func() {
success = p.page.MustEval(`() => {
Expand All @@ -1780,15 +1804,9 @@ func (p *rodPage) isPublishSuccessState() bool {
if (href.includes('/new/note-manager')) return true;

const text = document.body ? document.body.innerText : '';
if (/发布成功|提交成功|笔记发布成功/.test(text)) return true;
if (/笔记管理|草稿箱/.test(text)) return true;

const hasPublishEntry = /上传视频|上传图文|写长文/.test(text);
const hasTitleInput = !!document.querySelector('input[placeholder="填写标题会有更多赞哦"], input[placeholder*="填写标题"], input[placeholder*="标题"]');
const hasContentEditor = !!document.querySelector('div.tiptap.ProseMirror[contenteditable="true"], div.ProseMirror[contenteditable="true"], div[contenteditable="true"][role="textbox"]');
const buttons = Array.from(document.querySelectorAll('button')).map((el) => (el.innerText || el.textContent || '').trim());
const hasPublishButton = buttons.some((text) => /发布/.test(text));

return hasPublishEntry && !hasTitleInput && !hasContentEditor && !hasPublishButton;
return /上传视频|上传图文|写长文/.test(text);
}`).Bool()
})
return success
Expand All @@ -1806,7 +1824,7 @@ func (p *rodPage) waitForPublishConfirmation(ctx context.Context, pattern string
const text = document.body ? document.body.innerText : '';
return new RegExp(pattern).test(text);
}`, pattern).Bool()
}); err == nil && matched {
}); err == nil && matched && !p.isPublishEditorActive() {
return nil
}
if p.isPublishSuccessState() {
Expand Down
33 changes: 32 additions & 1 deletion internal/xhs/publisher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ func TestClickOnlySelfPublishButtonClicksCustomElement(t *testing.T) {
<html>
<head><meta charset="utf-8"></head>
<body>
<xhs-publish-btn is-publish="true" submit-disabled="false" submit-text="发布" style="display:block;width:120px;height:40px;" onclick="window.clickedPublish = true"></xhs-publish-btn>
<xhs-publish-btn is-publish="true" submit-disabled="false" submit-text="发布" style="display:block;width:120px;height:40px;"></xhs-publish-btn>
<script>
document.querySelector('xhs-publish-btn').addEventListener('publish', () => { window.clickedPublish = true; });
</script>
</body>
</html>`
page.MustNavigate("data:text/html;charset=utf-8," + url.PathEscape(html))
Expand Down Expand Up @@ -1748,6 +1751,34 @@ func TestConfirmOnlySelfPublishedAcceptsPublishedRedirect(t *testing.T) {
}
}

func TestPublishSuccessStateRejectsActiveEditorWithSidebarText(t *testing.T) {
page := testPage(t)

html := `<!doctype html>
<html>
<head><meta charset="utf-8"></head>
<body>
<nav>首页 笔记管理 数据看板 草稿箱</nav>
<main>
<input placeholder="填写标题会有更多赞哦" value="AI科技晚报 | 26.06.08 18:00">
<div class="tiptap ProseMirror" contenteditable="true" role="textbox">#AI资讯[话题]#</div>
<xhs-publish-btn is-publish="true" submit-disabled="false" submit-text="发布" style="display:block;width:680px;height:90px;"></xhs-publish-btn>
</main>
</body>
</html>`
page.MustNavigate("data:text/html," + url.PathEscape(html))
page.MustWaitLoad()
page.MustElement("body")

rodPage := &rodPage{page: page}
if !rodPage.isPublishEditorActive() {
t.Fatal("publish editor should be active")
}
if rodPage.isPublishSuccessState() {
t.Fatal("active publish editor with sidebar text must not be treated as success")
}
}

func TestApplyOriginalDeclarationChecksUncheckedOriginalBox(t *testing.T) {
page := testPage(t)

Expand Down