Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | const { matchesState } = require('../../lib/index'); // @ts-check const { Machine } = require('../../lib/index'); const { getSimplePathsAsArray } = require('../../lib/graph'); const puppeteer = require('puppeteer'); const assert = require('chai').assert; const createInstagramMachine = page => Machine( { initial: 'home', states: { home: { initial: 'loading', states: { loading: { on: { HOME_LOADED: 'loaded' } }, loaded: {} }, on: { LOG_IN_LINK: 'login' } }, login: { initial: 'start', states: { start: { on: { ENTER_USERNAME: 'username' } }, username: { on: { ENTER_PASSWORD: 'password' } }, password: {} }, on: { LOG_IN: [ { target: 'suspicious', cond: 'isSuspicious' }, { target: 'feed' } ] } }, suspicious: {}, feed: { initial: 'loading', states: { loading: { on: { FEED_LOADED: 'loaded' } }, loaded: {} }, on: { PROFILE_CLICK: 'profile' } }, profile: {} } }, { guards: { isSuspicious: () => false } } ); async function init() { const instagramMachine = createInstagramMachine(); const paths = getSimplePathsAsArray(instagramMachine); const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://instagram.com'); const eventMap = { HOME_LOADED: async page => { return true; }, LOG_IN_LINK: async page => { const link = await page.$('[href="/accounts/login/"]'); await link.click(); }, ENTER_USERNAME: async page => { await page.waitFor('[aria-label="Phone number, username, or email"]'); await new Promise(res => { setTimeout(() => { res(); }, 2000); }); const input = await page.$( '[aria-label="Phone number, username, or email"]' ); await input.type('davidkpiano'); }, ENTER_PASSWORD: async page => { const input = await page.$('[type="password"]'); await input.type('asdf!'); }, LOG_IN: async page => { const logInButton = await page.$( '#react-root > section > main > div > article > div > div:nth-child(1) > div > form > span > button' ); await logInButton.click(); }, FEED_LOADED: async page => { await page.waitFor('article header a'); }, PROFILE_CLICK: async page => { const button = await page.$('article header a'); console.log(button); await button.click(); } }; const profilePath = paths.filter(path => path.state === 'profile')[0]; const subPaths = profilePath.paths[profilePath.paths.length - 1]; console.dir(subPaths, { depth: null }); let currentState = instagramMachine.initialState; for (let i = 0; i < subPaths.length; i++) { const subPath = subPaths[i]; // make sure currentstate is correct console.log(subPath.state, currentState.value); assert.ok(matchesState(subPath.state, currentState.value)); console.log('STATE', subPath.state); console.log('EVENT', subPath.event); // wait 1 second await new Promise(res => setTimeout(res, 1000)); // execute event const execEvent = eventMap[subPath.event]; await execEvent(page); currentState = instagramMachine.transition(currentState, subPath.event); } } init(); |