Skip to content

Instantly share code, notes, and snippets.

@johncmunson
Created December 10, 2023 03:46
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 johncmunson/9ff447ea7acfb267556748e068a049de to your computer and use it in GitHub Desktop.
Save johncmunson/9ff447ea7acfb267556748e068a049de to your computer and use it in GitHub Desktop.
Automate Expensify Expense Report
// 1. Create new expense report and add items to it
// 2. Click on Details and set Workspace equal to Drive Social Media
// 3. Click on the first line item to open up the Edit Expense modal
// 4. Right click on the page and click on Inspect to open the browser devtools
// 5. In the devtools, open the Console tab
// 6. Paste the code below into the console and hit enter
// 7. Type the following and hit enter to start automating your report... automateReport()
const automateReport = async () => {
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
const fillOutMenuItems = async () => {
const labels = document.querySelectorAll('label')
const getDropdownMenuButton = (labelText) => {
const menuButton = [...labels]
.find((label) => label.textContent === labelText)
.nextElementSibling.nextElementSibling.querySelector('button')
return menuButton
}
const getDropdownMenuItem = (labelText, menuItemText) => {
const menu = getDropdownMenuButton(labelText).nextElementSibling
const listItems = menu.querySelectorAll('li')
let foundItem
listItems.forEach((li) => {
const anchor = li.querySelector('a')
if (anchor && anchor.textContent.trim() === menuItemText) {
foundItem = anchor
}
})
return foundItem
}
const categoryLabel = 'Category'
const softwareText = 'Software & Licenses'
getDropdownMenuButton(categoryLabel).click()
await sleep(700)
getDropdownMenuItem(categoryLabel, softwareText).click()
await sleep(700)
const classesLabel = 'Classes' //
const administrativeText = 'Administrative'
getDropdownMenuButton(classesLabel).click()
await sleep(700)
getDropdownMenuItem(classesLabel, administrativeText).click()
await sleep(700)
const customersLabel = 'Customers/Projects'
const noClientText = '1 - No Client Involved/DSM'
getDropdownMenuButton(customersLabel).click()
await sleep(700)
getDropdownMenuItem(customersLabel, noClientText).click()
await sleep(700)
}
const getNextButton = () => document.querySelector('#megaEdit_next')
while (!getNextButton().classList.contains('disabled')) {
await fillOutMenuItems()
getNextButton().click()
await sleep(700)
}
await fillOutMenuItems()
document.querySelector('#megaEdit_saveButton').click()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment