Skip to content

Commit

Permalink
Merge branch 'master' into feat/reuse-browser
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-hauser authored Oct 5, 2024
2 parents 0db2232 + cbbf9b7 commit 267521d
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum CompanyTypes {
behatsdaa = 'behatsdaa',
beyahadBishvilha = 'beyahadBishvilha',
oneZero = 'oneZero',
pagi = 'pagi',
}

export const SCRAPERS = {
Expand Down Expand Up @@ -101,6 +102,10 @@ export const SCRAPERS = {
name: 'Behatsdaa',
loginFields: ['id', PASSWORD_FIELD],
},
[CompanyTypes.pagi]: {
name: 'Pagi',
loginFields: ['username', PASSWORD_FIELD],
},
};

export enum ScraperProgressTypes {
Expand Down
4 changes: 3 additions & 1 deletion src/scrapers/base-isracard-amex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ interface ScrapedTransaction {
moreInfo?: string;
dealSumOutbound: boolean;
currencyId: string;
currentPaymentCurrency: string;
dealSum: number;
fullPaymentDate?: string;
fullPurchaseDate?: string;
Expand Down Expand Up @@ -190,8 +191,9 @@ function convertTransactions(txns: ScrapedTransaction[], processedDate: string):
date: txnMoment.toISOString(),
processedDate: currentProcessedDate,
originalAmount: isOutbound ? -txn.dealSumOutbound : -txn.dealSum,
originalCurrency: convertCurrency(txn.currencyId),
originalCurrency: convertCurrency(txn.currentPaymentCurrency ?? txn.currencyId),
chargedAmount: isOutbound ? -txn.paymentSumOutbound : -txn.paymentSum,
chargedCurrency: convertCurrency(txn.currencyId),
description: isOutbound ? txn.fullSupplierNameOutbound : txn.fullSupplierNameHeb,
memo: txn.moreInfo || '',
installments: getInstallmentsInfo(txn) || undefined,
Expand Down
3 changes: 3 additions & 0 deletions src/scrapers/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import MercantileScraper from './mercantile';
import MizrahiScraper from './mizrahi';
import OneZeroScraper from './one-zero';
import OtsarHahayalScraper from './otsar-hahayal';
import PagiScraper from './pagi';
import UnionBankScraper from './union-bank';
import VisaCalScraper from './visa-cal';
import YahavScraper from './yahav';
Expand Down Expand Up @@ -63,6 +64,8 @@ export default function createScraper(options: ScraperOptions): Scraper<ScraperC
return new OneZeroScraper(options);
case CompanyTypes.behatsdaa:
return new BehatsdaaScraper(options);
case CompanyTypes.pagi:
return new PagiScraper(options);
default:
return assertNever(options.companyId, `unknown company id ${options.companyId}`);
}
Expand Down
1 change: 1 addition & 0 deletions src/scrapers/one-zero.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export default class OneZeroScraper extends BaseScraper<ScraperSpecificCredentia
const hasInstallments = movement.transaction?.enrichment?.recurrences?.some((x) => x.isRecurrent);
const modifier = movement.creditDebit === 'DEBIT' ? -1 : 1;
return ({
identifier: movement.movementId,
date: movement.valueDate,
chargedAmount: (+movement.movementAmount) * modifier,
chargedCurrency: movement.movementCurrency,
Expand Down
50 changes: 50 additions & 0 deletions src/scrapers/pagi.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { SCRAPERS } from '../definitions';
import { exportTransactions, extendAsyncTimeout, getTestsConfig, maybeTestCompanyAPI } from '../tests/tests-utils';
import { LoginResults } from './base-scraper-with-browser';
import PagiScraper from './pagi';


const COMPANY_ID = 'pagi'; // TODO this property should be hard-coded in the provider
const testsConfig = getTestsConfig();

describe('Pagi legacy scraper', () => {
beforeAll(() => {
extendAsyncTimeout(); // The default timeout is 5 seconds per async test, this function extends the timeout value
});
test('should expose login fields in scrapers constant', () => {
expect(SCRAPERS.pagi).toBeDefined();
expect(SCRAPERS.pagi.loginFields).toContain('username');
expect(SCRAPERS.pagi.loginFields).toContain('password');
});

maybeTestCompanyAPI(COMPANY_ID, (config) => config.companyAPI.invalidPassword)('should fail on invalid user/password"', async () => {
const options = {
...testsConfig.options,
companyId: COMPANY_ID,
};

const scraper = new PagiScraper(options);

const result = await scraper.scrape({ username: 'e10s12', password: '3f3ss3d' });

expect(result).toBeDefined();
expect(result.success).toBeFalsy();
expect(result.errorType).toBe(LoginResults.InvalidPassword);
});

maybeTestCompanyAPI(COMPANY_ID)('should scrape transactions"', async () => {
const options = {
...testsConfig.options,
companyId: COMPANY_ID,
};

const scraper = new PagiScraper(options);
const result = await scraper.scrape(testsConfig.credentials.pagi);
expect(result).toBeDefined();
const error = `${result.errorType || ''} ${result.errorMessage || ''}`.trim();
expect(error).toBe('');
expect(result.success).toBeTruthy();

exportTransactions(COMPANY_ID, result.accounts || []);
});
});
12 changes: 12 additions & 0 deletions src/scrapers/pagi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import BeinleumiGroupBaseScraper from './base-beinleumi-group';

class PagiScraper extends BeinleumiGroupBaseScraper {
BASE_URL = 'https://online.pagi.co.il/';

LOGIN_URL = `${this.BASE_URL}/MatafLoginService/MatafLoginServlet?bankId=PAGIPORTAL&site=Private&KODSAFA=HE`;

TRANSACTIONS_URL = `${this.BASE_URL}/wps/myportal/FibiMenu/Online/OnAccountMngment/OnBalanceTrans/PrivateAccountFlow`;

}

export default PagiScraper;
19 changes: 12 additions & 7 deletions src/scrapers/yahav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const INVALID_DETAILS_SELECTOR = '.ui-dialog-buttons';
const CHANGE_PASSWORD_OLD_PASS = 'input#ef_req_parameter_old_credential';
const BASE_WELCOME_URL = `${BASE_URL}main/home`;

const ACCOUNT_ID_SELECTOR = '.dropdown-dir .selected-item-top';
const ACCOUNT_ID_SELECTOR = 'span.portfolio-value[ng-if="mainController.data.portfolioList.length === 1"]';
const ACCOUNT_DETAILS_SELECTOR = '.account-details';
const DATE_FORMAT = 'DD/MM/YYYY';

Expand Down Expand Up @@ -59,12 +59,17 @@ function getPossibleLoginResults(page: Page): PossibleLoginResults {
return urls;
}

async function getAccountID(page: Page) {
const selectedSnifAccount = await page.$eval(`${ACCOUNT_ID_SELECTOR}`, (option) => {
return (option as HTMLElement).innerText;
});

return selectedSnifAccount;
async function getAccountID(page: Page): Promise<string> {
try {
const selectedSnifAccount = await page.$eval(ACCOUNT_ID_SELECTOR, (element: Element) => {
return element.textContent as string;
});

return selectedSnifAccount;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to retrieve account ID. Possible outdated selector '${ACCOUNT_ID_SELECTOR}: ${errorMessage}`);
}
}

function getAmountData(amountStr: string) {
Expand Down
3 changes: 2 additions & 1 deletion src/tests/.tests-config.tpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ module.exports = {
// yahav: {username: '', nationalID: '', password: ''}
// beyahadBishvilha: { id: '', password: ''},
// behatsdaa: { id: '', password: ''},
// oneZero: { email: '', password: '', otpCode: '', otpToken: null }
// oneZero: { email: '', password: '', otpCode: '', otpToken: null },
// pagi: { username: '', password: ''},
},
companyAPI: { // enable companyAPI to execute tests against the real companies api
enabled: true,
Expand Down

0 comments on commit 267521d

Please sign in to comment.