diff --git a/.claude/commands/corpus-loop.md b/.claude/commands/corpus-loop.md new file mode 100644 index 0000000..fe602c1 --- /dev/null +++ b/.claude/commands/corpus-loop.md @@ -0,0 +1,57 @@ +--- +argument-hint: [corpus_slug] +description: uses Playwright MCP and the `corpus:view` to parse page elements +--- + +- using Playwright MCP, navigate to `http://localhost:3001/corpus/$1/gitcasso` +- the page will have a div with id `gitcasso-comment-spots`, wait 500ms for it to settle +- inside the `gitcasso-comment-spots` div you will see something like this: + +```json +{ + "url": "https://github.com/diffplug/selfie/issues/523", + "allTextAreas": [ + { + "textarea": "id='feedback' name='feedback' className='form-control width-full mb-2'", + "spot": "NO_SPOT" + }, + { + "textarea": "id=':rn:' name='' className='prc-Textarea-TextArea-13q4j overtype-input'", + "spot": { + "domain": "github.com", + "number": 523, + "slug": "diffplug/selfie", + "title": "TODO_TITLE", + "type": "GH_ISSUE_ADD_COMMENT", + "unique_key": "github.com:diffplug/selfie:523" + } + } + ] +} +``` + +- this output means that this page is simulating the url `https://github.com/diffplug/selfie/issues/523` +- every textarea on the page is represented +- `NO_SPOT` means that the spot was not enhanced +- `type: GH_ISSUE_ADD_COMMENT` means that it was enhanced by whichever implementation of `CommentEnhancer` returns the spot type `GH_ISSUE_ADD_COMMENT` +- if you search for that string in `src/lib/enhancers` you will find the correct one +- the `tryToEnhance` method returned a `CommentSpot`, and that whole data is splatted out above + +If you make a change to the code of the enhancer, you can click the button with id `gitcasso-rebuild-btn`. It will trigger a rebuild of the browser extension, and then refresh the page. You'll be able to see the effects of your change in the `gitcasso-comment-spots` div described above. + +## Common extraction workflow + +If you see `"title": "TODO_TITLE"` or similar hardcoded `TODO` values in the JSON output, this indicates the enhancer needs some kind of extraction implemented: + +1. **Find the enhancer**: Search for the `type` value (e.g., `GH_ISSUE_ADD_COMMENT`) in `src/lib/enhancers/` +2. **Implement extraction**: Replace hardcoded title with DOM extraction: + ```javascript + const title = document.querySelector('main h1')!.textContent.replace(/\s*#\d+$/, '').trim() + ``` +4. **Test with rebuild**: Click the 🔄 button to rebuild and verify the title appears correctly in the JSON + +## Extraction code style + +- Don't hedge your bets and write lots of fallback code or strings of `?.`. Have a specific piece of data you want to get, use non-null `!` assertions where necessary to be clear about getting. +- If a field is empty, represent it with an empty string. Don't use placeholders when extracting data. +- The pages we are scraping are going to change over time, and it's easier to fix broken ones if we know exactly what used to work. If the code has lots of branching paths, it's harder to tell what it was doing. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4ce6898..76301ea 100644 --- a/.gitignore +++ b/.gitignore @@ -17,9 +17,5 @@ dist/ .DS_Store Thumbs.db -# playright +# playwright .playwright-mcp/ -browser-extension/dist-playground/ -browser-extension/playwright-report/ -browser-extension/playwright/ -browser-extension/test-results/ diff --git a/CLAUDE.md b/CLAUDE.md index 2edfa38..2fbb37a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,3 @@ -Please refer to `CONTRIBUTING.md` and `README.md`. +Refer to `CONTRIBUTING.md` for the project's architecture and useful commands. Whenever you complete a task, if you wish some info had been provided to you ahead of time instead of figuring it out from scratch, you have permission to edit this `CLAUDE.md` to add any helpful context. diff --git a/src/lib/enhancers/github/githubIssueAddComment.tsx b/src/lib/enhancers/github/githubIssueAddComment.tsx index a36de96..70f7fed 100644 --- a/src/lib/enhancers/github/githubIssueAddComment.tsx +++ b/src/lib/enhancers/github/githubIssueAddComment.tsx @@ -42,7 +42,10 @@ export class GitHubIssueAddCommentEnhancer implements CommentEnhancer { @@ -17,9 +18,12 @@ export class GitHubIssueNewCommentEnhancer implements CommentEnhancer { @@ -38,13 +41,19 @@ export class GitHubPRNewCommentEnhancer implements CommentEnhancer function updateCommentSpotDisplay() { const textareas = document.querySelectorAll('textarea'); - const spotsFound = []; + const allTextAreas = []; for (const textarea of textareas) { - const forValue = 'id=' + textarea.id + ' name=' + textarea.name + ' className=' + textarea.className; + const forValue = "id='" + textarea.id + "' name='" + textarea.name + "' className='" + textarea.className + "'"; const enhancedItem = window.gitcassoTextareaRegistry ? window.gitcassoTextareaRegistry.get(textarea) : undefined; if (enhancedItem) { - spotsFound.push({ - for: forValue, + allTextAreas.push({ + textarea: forValue, spot: enhancedItem.spot, - title: enhancedItem.enhancer.tableTitle(enhancedItem.spot), }); } else { - spotsFound.push({ - for: forValue, + allTextAreas.push({ + textarea: forValue, spot: 'NO_SPOT', }); } } - - console.log('Enhanced textareas:', spotsFound.filter(s => s.spot !== 'NO_SPOT').length); - console.log('All textareas on page:', textareas.length); - commentSpotDisplay.innerHTML = '
${urlParts.href}\\n' + JSON.stringify(spotsFound, null, 2) + '
'; + const harness = { + url: '${urlParts.href}', + allTextAreas: allTextAreas + } + commentSpotDisplay.innerHTML = '
' + JSON.stringify(harness, null, 1) + '
'; } // Initial update @@ -508,9 +508,6 @@ function createCommentSpotDisplayScript(urlParts: ReturnType setTimeout(updateCommentSpotDisplay, 400); setTimeout(updateCommentSpotDisplay, 800); - // Update display periodically - setInterval(updateCommentSpotDisplay, 2000); - document.body.appendChild(commentSpotDisplay); ` } diff --git a/tests/corpus/_corpus-index.ts b/tests/corpus/_corpus-index.ts index d985669..628106d 100644 --- a/tests/corpus/_corpus-index.ts +++ b/tests/corpus/_corpus-index.ts @@ -17,6 +17,11 @@ export const CORPUS: Record = { type: 'html', url: 'https://github.com/diffplug/gitcasso/issues/56', }, + gh_issue_new_populated: { + description: 'a new issue wiht some fields filled out', + type: 'html', + url: 'https://github.com/diffplug/gitcasso/issues/new', + }, gh_issue_populated_comment: { description: 'comment text box has some text', type: 'html', diff --git a/tests/corpus/gh_issue_new_populated.html b/tests/corpus/gh_issue_new_populated.html new file mode 100644 index 0000000..85f6804 --- /dev/null +++ b/tests/corpus/gh_issue_new_populated.html @@ -0,0 +1,1586 @@ + + + + + + + + + + + + + + + +New Issue + +
+
+ +
+ Skip to content + + + + + + + + +
+
+ + + + + + +
+
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + +
View cavia-porcellus's profile

Create new issue

Add a description
Markdown input: edit mode selected.

Metadata

Assignees

No one -

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone
    Remember, contributions to this repository should follow its contributing guidelines.
    +
    +
    +
    +
    +
    + + + + + + + + +
    +
    New Issue
    +
    14 results
    + + \ No newline at end of file diff --git a/tests/lib/enhancers/github.test.ts b/tests/lib/enhancers/github.test.ts index d4fc82c..bc7af29 100644 --- a/tests/lib/enhancers/github.test.ts +++ b/tests/lib/enhancers/github.test.ts @@ -48,11 +48,13 @@ describe('github', () => { "domain": "github.com", "number": 517, "slug": "diffplug/selfie", - "title": "TODO_TITLE", + "title": "Add "VCR" functionality + #517", "type": "GH_PR_ADD_COMMENT", "unique_key": "github.com:diffplug/selfie:517", }, - "title": "TITLE_TODO", + "title": "Add "VCR" functionality + #517", "upperDecoration": { { "for": "id=pull_request_body name=pull_request[body] className=js-comment-field js-paste-markdown js-task-list-field js-quick-submit FormControl-textarea CommentBox-input js-size-to-fit size-to-fit js-session-resumable js-saved-reply-shortcut-comment-field CommentBox-input--large overtype-input", "spot": { + "base": "main", "domain": "github.com", - "slug": "diffplug/selfie/main...cavia-porcellus:selfie:main", + "head": "cavia-porcellus:selfie:main", + "slug": "diffplug/selfie", + "title": "Update README.md", "type": "GH_PR_NEW_COMMENT", - "unique_key": "github.com:diffplug/selfie/main...cavia-porcellus:selfie:main", + "unique_key": "github.com:diffplug/selfie:main...cavia-porcellus:selfie:main", }, - "title": "TITLE_TODO", + "title": "Update README.md", "upperDecoration": New PR @@ -94,7 +99,7 @@ describe('github', () => { className="font-mono text-muted-foreground text-sm" > - diffplug/selfie/main...cavia-porcellus:selfie:main + diffplug/selfie , @@ -112,6 +117,35 @@ describe('github', () => { ] `) }) + withCorpus('gh_issue_new_populated').it('has enhancement on initial page load', async () => { + expect(enhancements(document, window)).toMatchInlineSnapshot(` + [ + { + "for": "id=:r34: name=null className=prc-Textarea-TextArea-13q4j focus-visible overtype-input", + "spot": { + "domain": "github.com", + "slug": "diffplug/gitcasso", + "title": "New issue title", + "type": "GH_ISSUE_NEW_COMMENT", + "unique_key": "github.com:diffplug/gitcasso:new", + }, + "title": "New issue title", + "upperDecoration": + + New Issue + + + + diffplug/gitcasso + + + , + }, + ] + `) + }) withCorpus('gh_issue_populated_comment').it('should create the correct spot object', async () => { expect(enhancements(document, window)).toMatchInlineSnapshot(` [ @@ -121,11 +155,11 @@ describe('github', () => { "domain": "github.com", "number": 523, "slug": "diffplug/selfie", - "title": "TODO_TITLE", + "title": "[jvm] docs for VCR", "type": "GH_ISSUE_ADD_COMMENT", "unique_key": "github.com:diffplug/selfie:523", }, - "title": "TITLE_TODO", + "title": "[jvm] docs for VCR", "upperDecoration": { expect(enhancements(document, window)).toMatchInlineSnapshot(` [ { - "for": "id=feedback name=feedback className=form-control width-full mb-2 overtype-input", - "spot": { - "domain": "github.com", - "slug": "diffplug/selfie", - "type": "GH_ISSUE_NEW_COMMENT", - "unique_key": "github.com:diffplug/selfie:new", - }, - "title": "New Issue", - "upperDecoration": - - New Issue - - - - diffplug/selfie - - - , + "for": "id=feedback name=feedback className=form-control width-full mb-2", + "spot": "NO_SPOT", }, ] `) @@ -184,11 +200,11 @@ describe('github', () => { "domain": "github.com", "number": 56, "slug": "diffplug/gitcasso", - "title": "TODO_TITLE", + "title": "what about the draft?", "type": "GH_ISSUE_ADD_COMMENT", "unique_key": "github.com:diffplug/gitcasso:56", }, - "title": "TITLE_TODO", + "title": "what about the draft?", "upperDecoration": { "domain": "github.com", "number": 56, "slug": "diffplug/gitcasso", - "title": "TODO_TITLE", + "title": "what about the draft?", "type": "GH_ISSUE_ADD_COMMENT", "unique_key": "github.com:diffplug/gitcasso:56", }, - "title": "TITLE_TODO", + "title": "what about the draft?", "upperDecoration": { "domain": "github.com", "number": 58, "slug": "diffplug/gitcasso", - "title": "TODO_TITLE", + "title": "Feat/expand corpus + + #58", "type": "GH_PR_ADD_COMMENT", "unique_key": "github.com:diffplug/gitcasso:58", }, - "title": "TITLE_TODO", + "title": "Feat/expand corpus + + #58", "upperDecoration":