Skip to content

Instantly share code, notes, and snippets.

@coderbyheart
Last active August 26, 2023 06:25
Show Gist options
  • Save coderbyheart/4977f041a277408363e35df9d9edd314 to your computer and use it in GitHub Desktop.
Save coderbyheart/4977f041a277408363e35df9d9edd314 to your computer and use it in GitHub Desktop.
Clean Twitter Account with Playwright
import { test } from "@playwright/test";
import { appendFile, readFile } from "fs/promises";
const username = "coderbyheart";
const password = "xxx";
test("remove old tweets", async ({ page }) => {
await page.goto("https://twitter.com/");
await page.getByTestId("loginButton").click();
await page.getByLabel("Phone, email, or username").fill(username);
await page.getByRole("button", { name: "Next" }).click();
await page.getByLabel("Password", { exact: true }).fill(password);
await page.getByLabel("Password", { exact: true }).press("Enter");
await page.getByTestId("AppTabBar_Profile_Link").click();
await page
.getByRole("button", { name: "Refuse non-essential cookies" })
.click();
const tweets = (await readFile("./tweets.txt", "utf-8"))
.split("\n")
.map((s) => s.trim());
const deleted = (await readFile("./deleted.txt", "utf-8"))
.split("\n")
.map((s) => s.trim());
for (const tweet of tweets.filter((s) => !deleted.includes(s))) {
await page.goto(`https://twitter.com/${username}/status/${tweet}`);
await new Promise((resolve) => setTimeout(resolve, 8000));
await page
.locator(
`a[href="/${username}/status/${tweet}"] >> xpath=../../../../../../.. >> [aria-label="More"]`
)
.click();
await page
.getByRole("menuitem", { name: "Delete" })
.locator("div")
.nth(2)
.click();
await page.getByTestId("confirmationSheetConfirm").click();
await appendFile("./deleted.txt", `${tweet}\n`, "utf-8");
}
});
import { test } from "@playwright/test";
const username = 'coderbyheart'
const password = 'xxx'
test("unfollow all", async ({ page }) => {
await page.goto("https://twitter.com/");
await page.getByTestId("loginButton").click();
await page.getByLabel("Phone, email, or username").fill(username);
await page.getByRole("button", { name: "Next" }).click();
await page.getByLabel("Password", { exact: true }).fill(password);
await page.getByLabel("Password", { exact: true }).press("Enter");
await page
.getByRole("link", { name: "Markus Tacker | @coderbyheart@chaos.social" })
.click();
await page.getByRole("link", { name: "Followers" }).click();
do {
await page.goto(`https://twitter.com/${username}/followers`);
await page
.locator('[aria-label="Timeline: Followers"] [aria-label="More"]')
.first()
.isVisible();
await new Promise((resolve) => setTimeout(resolve, 1000));
for (const el of await page
.locator('[aria-label="Timeline: Followers"] [aria-label="More"]')
.all()) {
await el.click();
await page.getByText("Remove this follower").click();
const confirm = page.getByTestId("confirmationSheetConfirm");
await confirm.isVisible();
const title = confirm.locator("..").locator("..").locator("div").first();
console.log(await title.textContent());
await confirm.click();
}
} while (true);
});
import { test } from "@playwright/test";
test("unfollow all", async ({ page }) => {
await page.goto("https://twitter.com/");
await page.getByTestId("loginButton").click();
await page.getByLabel("Phone, email, or username").fill("coderbyheart");
await page.getByRole("button", { name: "Next" }).click();
await page.getByLabel("Password", { exact: true }).fill("xxx");
await page.getByLabel("Password", { exact: true }).press("Enter");
await page
.getByRole("link", { name: "Markus Tacker | @coderbyheart@chaos.social" })
.click();
await page.getByRole("link", { name: "Following" }).click();
do {
await page.goto("https://twitter.com/coderbyheart/following");
await page
.locator('[aria-label="Timeline: Following"] span:has-text("Following")')
.first()
.isVisible();
await new Promise((resolve) => setTimeout(resolve, 1000));
for (const el of await page
.locator('[aria-label="Timeline: Following"] span:has-text("Following")')
.all()) {
await el.click();
const confirm = page.getByTestId("confirmationSheetConfirm");
await confirm.isVisible();
const title = confirm.locator("..").locator("..").locator("h1");
console.log(await title.textContent());
await confirm.click();
}
} while (true);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment