diff --git a/package-lock.json b/package-lock.json index f4da796a9..59d71206a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,7 @@ "@babel/core": "^7.23.0", "@babel/preset-env": "^7.22.20", "@babel/preset-react": "^7.22.15", - "@playwright/experimental-ct-react": "^1.43.1", + "@playwright/experimental-ct-react": "^1.45.3", "@playwright/test": "^1.43.1", "@svgr/webpack": "^8.1.0", "@types/node": "^18.18.4", @@ -3246,33 +3246,63 @@ } }, "node_modules/@playwright/experimental-ct-core": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/@playwright/experimental-ct-core/-/experimental-ct-core-1.44.0.tgz", - "integrity": "sha512-0PnvZVIrZW079Q+nyX5cz+MHpWd7G5t+cdtrAjREUk0+BbJ2A/KXnuHdtmw/OVrqQjwMxUWdSv9hXpi2lnOJYA==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/experimental-ct-core/-/experimental-ct-core-1.45.3.tgz", + "integrity": "sha512-uYcWBxRPu2G2Mj2e+XUxRBzRNnG/Yz0A5DVWFewiG3qEfC92MaGYGxmzKeFeU9NcMA2fWwaqB3XWHXjn9qSM5Q==", "dev": true, "dependencies": { - "playwright": "1.44.0", - "playwright-core": "1.44.0", + "playwright": "1.45.3", + "playwright-core": "1.45.3", "vite": "^5.2.8" }, "engines": { - "node": ">=16" + "node": ">=18" + } + }, + "node_modules/@playwright/experimental-ct-core/node_modules/playwright": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.3.tgz", + "integrity": "sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==", + "dev": true, + "dependencies": { + "playwright-core": "1.45.3" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/@playwright/experimental-ct-core/node_modules/playwright-core": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.3.tgz", + "integrity": "sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" } }, "node_modules/@playwright/experimental-ct-react": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/@playwright/experimental-ct-react/-/experimental-ct-react-1.44.0.tgz", - "integrity": "sha512-2ytru6FGJ2D7sk5DQE0hYi8S0zkcGFWfGSX1h8JoeKKGCZPOCgqloM+Qfqijud0xp15f952cnXO1hUWCILXsng==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/experimental-ct-react/-/experimental-ct-react-1.45.3.tgz", + "integrity": "sha512-cEgiZ2+DqVCeFJWJdHgOUwhlEof41Rg1GX48FtMX/xrjAnxs2ccqqAXMILD+mVV1ftsC2jeS1EiRLoAmf8QXgA==", "dev": true, "dependencies": { - "@playwright/experimental-ct-core": "1.44.0", + "@playwright/experimental-ct-core": "1.45.3", "@vitejs/plugin-react": "^4.2.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@playwright/test": { diff --git a/package.json b/package.json index b58cafab7..cc94b4dd4 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "@babel/core": "^7.23.0", "@babel/preset-env": "^7.22.20", "@babel/preset-react": "^7.22.15", - "@playwright/experimental-ct-react": "^1.43.1", + "@playwright/experimental-ct-react": "^1.45.3", "@playwright/test": "^1.43.1", "@svgr/webpack": "^8.1.0", "@types/node": "^18.18.4", diff --git a/src/components/NavItems/Assistant/AssistantRuleBook.jsx b/src/components/NavItems/Assistant/AssistantRuleBook.jsx index 5a628ffc2..8683d7028 100644 --- a/src/components/NavItems/Assistant/AssistantRuleBook.jsx +++ b/src/components/NavItems/Assistant/AssistantRuleBook.jsx @@ -227,6 +227,7 @@ export const ASSISTANT_ACTIONS = [ KNOWN_LINKS.TELEGRAM, KNOWN_LINKS.FACEBOOK, KNOWN_LINKS.TWITTER, + KNOWN_LINKS.MASTODON, ], cTypes: [CONTENT_TYPE.VIDEO], exceptions: [], diff --git a/src/components/NavItems/Assistant/AssistantScrapeResults/AssistantTextResult.jsx b/src/components/NavItems/Assistant/AssistantScrapeResults/AssistantTextResult.jsx index b7605b61a..8961e8f8a 100644 --- a/src/components/NavItems/Assistant/AssistantScrapeResults/AssistantTextResult.jsx +++ b/src/components/NavItems/Assistant/AssistantScrapeResults/AssistantTextResult.jsx @@ -69,7 +69,7 @@ const AssistantTextResult = () => { return ( - + currentIndex) { + // If span doesn't start before the current index, add unlighlighted text childElems.push(text.substring(currentIndex, hSpanStart)); } @@ -48,15 +34,12 @@ function treeMapToElementsRecursive( hSpanStart < span.start ? span.start : hSpanStart; const boundedEnd = hSpanEnd > span.end ? span.end : hSpanEnd; if (wrapFunc) { - // console.log("Wrapping: ", text.substring(boundedStart, boundedEnd)); + // Add parts of text that needs to be wrapped in wrapFunc() childElems.push( wrapFunc(text.substring(boundedStart, boundedEnd), hSpan), ); } else { - // console.log( - // "Not wrapping: ", - // text.substring(boundedStart, boundedEnd), - // ); + // No wrapFunc(), inserting plaintext childElems.push(text.substring(boundedStart, boundedEnd)); } @@ -81,7 +64,14 @@ function treeMapToElementsRecursive( ), ); } - return React.createElement(treeElem.tag, null, childElems); + + //Collect attributes + let attributes = {}; + if (treeElem.attributes) { + attributes = treeElem.attributes; + } + + return React.createElement(treeElem.tag, attributes, childElems); } /** diff --git a/src/redux/sagas/assistantSaga.jsx b/src/redux/sagas/assistantSaga.jsx index 4d25451b4..d90c72db0 100644 --- a/src/redux/sagas/assistantSaga.jsx +++ b/src/redux/sagas/assistantSaga.jsx @@ -637,6 +637,7 @@ const filterAssistantResults = ( videoList = scrapeResult.videos; } break; + case KNOWN_LINKS.MASTODON: case KNOWN_LINKS.TELEGRAM: case KNOWN_LINKS.VK: if (scrapeResult.images.length > 0) { diff --git a/tests/e2e/assistant.spec.js b/tests/e2e/assistant.spec.js index 60fb733f6..2f840fcf3 100644 --- a/tests/e2e/assistant.spec.js +++ b/tests/e2e/assistant.spec.js @@ -3,7 +3,8 @@ import { test, expect } from './fixtures'; const MediaType = { video: "video", - image: "image" + image: "image", + none: "none", }; const MediaVideoStatus = { @@ -27,6 +28,8 @@ const MediaServices = { videoDownloadTiktok: "assistant_video_download_tiktok", }; + + [ // Twitter image post { @@ -125,22 +128,21 @@ const MediaServices = { mediaStatus: MediaVideoStatus.iframe, services: [MediaServices.videoDownloadGeneric] }, - // Mastodon issues will be addressed very soon! - // // Mastodon link with youtube video link - // { - // url: "https://mstdn.social/@BBC/105203076554056414", - // mediaType: MediaType.video, - // mediaStatus: MediaVideoStatus.video, - // services: [] - // }, - // // Mastodon link with embedded video - // { - // url: "https://mstdn.social/@dtnsshow/112728823075224415", - // mediaType: MediaType.video, - // mediaStatus: MediaVideoStatus.video, - // services: [] - // }, -].forEach(({url, videoGridIndex, imageGridIndex, mediaType, mediaStatus, services}) => { + // Mastodon link with youtube video link + { + url: "https://mstdn.social/@BBC/105203076554056414", + mediaType: MediaType.video, + mediaStatus: MediaVideoStatus.video, + services: [] + }, + // Mastodon link with embedded video + { + url: "https://mstdn.social/@dtnsshow/112728823075224415", + mediaType: MediaType.video, + mediaStatus: MediaVideoStatus.video, + services: [MediaServices.videoDownload, MediaServices.metadata] + }, +].forEach(({url, videoGridIndex, imageGridIndex, mediaType, mediaStatus, services, hasScrapedText = true}) => { test(`Test assistant media services for url: ${url}`, async ({ page, extensionId }) => { // Navigate to the assistant page @@ -166,43 +168,58 @@ const MediaServices = { if(Number.isInteger(imageGridIndex)) await page.getByTestId("assistant-media-grid-image-"+imageGridIndex).click(); - // If expecting an image, check that the image is shown - if(mediaType === MediaType.image){ - await expect(page.getByTestId("assistant-media-image")).toBeVisible(); - } - - if(mediaType === MediaType.video){ - await expect(page.getByTestId("assistant-media-video-container")).toBeVisible(); - if(mediaStatus !== null && mediaStatus !== undefined){ - switch (mediaStatus) { - case MediaVideoStatus.iframe: - await expect(page.getByTestId("assistant-media-video-iframe")).toBeVisible(); - break; - case MediaVideoStatus.video: - await expect(page.getByTestId("assistant-media-video-tag")).toBeVisible(); - break; - case MediaVideoStatus.noEmbed: - await expect(page.getByTestId("assistant-media-video-noembed")).toBeVisible(); - break; + // Check that media exists for image and video posts and that all expected services are shown + switch(mediaType){ + case MediaType.image: + await expect(page.getByTestId("assistant-media-image")).toBeVisible(); + await checkMediaServices(page, services) + break; + case MediaType.video: + await expect(page.getByTestId("assistant-media-video-container")).toBeVisible(); + if(mediaStatus !== null && mediaStatus !== undefined){ + switch (mediaStatus) { + case MediaVideoStatus.iframe: + await expect(page.getByTestId("assistant-media-video-iframe")).toBeVisible(); + break; + case MediaVideoStatus.video: + await expect(page.getByTestId("assistant-media-video-tag")).toBeVisible(); + break; + case MediaVideoStatus.noEmbed: + await expect(page.getByTestId("assistant-media-video-noembed")).toBeVisible(); + break; + + } } - } + await checkMediaServices(page, services) + break; + case MediaType.none: + await expect(page.getByTestId("assistant-media-video-container")).not.toBeVisible(); + break; } - // Checks that expected services are shown - for( const serviceId of services){ - await expect(page.getByTestId(serviceId)).toBeVisible(); + if(hasScrapedText){ + await expect(page.getByTestId("assistant-text-scraped-text")).toBeVisible(); } - // Ensure disabled services are not showing - for( const serviceKey in MediaServices){ - const serviceId = MediaServices[serviceKey]; - if(!services.includes(serviceId)) - await expect(page.getByTestId(serviceId)).not.toBeVisible(); - } }); } ); +async function checkMediaServices(page, availableServices){ + // Checks that expected services are shown + for( const serviceId of availableServices){ + await expect(page.getByTestId(serviceId)).toBeVisible(); + } + + // Ensure disabled services are not showing + for( const serviceKey in MediaServices){ + const serviceId = MediaServices[serviceKey]; + if(!availableServices.includes(serviceId)) + await expect(page.getByTestId(serviceId)).not.toBeVisible(); + } + +} +