Skip to content

Instantly share code, notes, and snippets.

@MosheBerman
Last active June 4, 2020 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MosheBerman/49610eba1394a76b6e3d73f375f8b6cd to your computer and use it in GitHub Desktop.
Save MosheBerman/49610eba1394a76b6e3d73f375f8b6cd to your computer and use it in GitHub Desktop.
Automate DNA Clustering on Ancestry.com
/**
Tested in Google Chrome on macOS.
How to use:
Step 1: Navigate to Ancestry.com > DNA Matches > {A match} > Shared Matches
Step 2: Add a new custom group. (If you don't, the bottom group will be used.)
Step 2, optional: scroll down to load more shared matches. (Only loaded matches can be seen by the script.)
Step 3: Open the Developer Console.
Step 4: Paste this code into the console.
Step 5: Wait. The script is manually clicking buttons and it will take some time.
**/
/**
* Pull matches out of Web UI and manually click each one...
*/
const groups = Array.from(document.getElementsByClassName("secMatchGroup"))
/**
* Works in Chrome DevTools to pause.
* Source: https://stackoverflow.com/a/39914235
*/
const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* Process each row.
*/
const getButtonsInGroup = (group) => {
return Array.from(document.getElementsByClassName('groupAddBtn'))
}
/**
* Loops through all the buttons and processes eacj row.
*/
const iterateButtons = async (buttons, add) => {
if (add) {
await buttons.forEach(button => addRowToLastCluster(button))
} else {
await buttons.forEach(button => removeRowFromLastCluster(button))
}
}
/**
*
*/
const addRowToLastCluster = async (button) => {
button.click()
let groupButtons = Array.from(document.getElementsByClassName('checkInputLabel'))
let targetGroupLabel = groupButtons[groupButtons.length - 1]
if (!targetGroupLabel.previousElementSibling.checked) {
// Let's not DDOS Ancestry.
// This is more than how long a PUT takes my machine by 100ms.
await sleep(250)
targetGroupLabel.click()
}
button.click()
}
/**
*
*/
const removeRowFromLastCluster = (button) => {
button.click()
let groupButtons = Array.from(document.getElementsByClassName('checkInputLabel'))
let targetGroupLabel = groupButtons[groupButtons.length - 1]
if (targetGroupLabel.previousElementSibling.checked) {
targetGroupLabel.click()
}
button.click()
}
/**
* Process each group.
*
* @param group The list of relatives to cluster. (3rd Cousin, 4th Cousin, etc.)
* @param add If true, adds the group members to the most recent group. Otherwise, false, will remove.
*/
const iterateEachGroup = (group, add=true) => {
const buttons = getButtonsInGroup(group)
iterateButtons(buttons, add)
}
/**
* Run the script.
*/
iterateEachGroup(groups, true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment