csuf-en 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. package/cli.js +5 -0
  2. package/index.js +199 -0
  3. package/package.json +31 -0
package/cli.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { runScript } = require("./index");
4
+
5
+ runScript();
package/index.js ADDED
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+
3
+ const puppeteer = require("puppeteer");
4
+ const prompt = require("prompt-sync")();
5
+
6
+ function promptHeadlessOption() {
7
+ const response = prompt(
8
+ "Do you want to run Puppeteer in headless mode? (yes/no): "
9
+ ).toLowerCase();
10
+
11
+ if (response === "yes" || response === "y") {
12
+ return true;
13
+ } else if (response === "no" || response === "n") {
14
+ return false;
15
+ } else {
16
+ console.log("Please enter a valid option (yes/no).");
17
+ return promptHeadlessOption();
18
+ }
19
+ }
20
+
21
+ const headless = promptHeadlessOption();
22
+
23
+ if (headless === null) {
24
+ console.log("You must choose a mode (yes/no) before starting.");
25
+ process.exit(1);
26
+ }
27
+
28
+ if (headless) {
29
+ console.log("Puppeteer will run in headless mode.");
30
+ } else {
31
+ console.log("Puppeteer will run in non-headless mode.");
32
+ }
33
+
34
+ const CWID = prompt("Enter CWID: ");
35
+ const FIRST_NAME = prompt("Enter First Name: ");
36
+ const LAST_NAME = prompt("Enter Last Name: ");
37
+ const EMAIL = prompt("Enter Email: ");
38
+ const HOME_PHONE = prompt("Enter Home Phone: ");
39
+ const MOBILE_PHONE = prompt("Enter Mobile Phone: ");
40
+ const BIRTHDAY = prompt("Enter Birthday (DD/MM/YYYY): ");
41
+ const GENDER = prompt("Enter Gender: ");
42
+ const ADDRESS_LINE_1 = prompt("Enter Address Line 1: ");
43
+ const ADDRESS_LINE_2 = prompt("Enter Address Line 2: ");
44
+ const CITY = prompt("Enter City: ");
45
+ const STATE = prompt("Enter State: ");
46
+ const ZIP_CODE = prompt("Enter Zip Code: ");
47
+ const COUNTRY = prompt("Enter Country: ");
48
+
49
+ async function scrapeClassIds(browser) {
50
+ const page = await browser.newPage();
51
+ await page.goto(
52
+ "https://cmsweb.fullerton.edu/psc/CFULPRD/EMPLOYEE/SA/c/SA_LEARNER_SERVICES.CLASS_SEARCH.GBL?&public",
53
+ {
54
+ waitUntil: "networkidle2"
55
+ }
56
+ );
57
+ await page.setViewport({ width: 1080, height: 1024 });
58
+ await page.select("#SSR_CLSRCH_WRK_SUBJECT_SRCH\\$0", "ENGL");
59
+ await page.type("#SSR_CLSRCH_WRK_CATALOG_NBR\\$1", "101");
60
+ await page.select("#SSR_CLSRCH_WRK_SSR_EXACT_MATCH1\\$1", "T");
61
+ await page.click("#SSR_CLSRCH_WRK_SSR_OPEN_ONLY\\$3");
62
+ await page.click("#CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH");
63
+ await page.waitForSelector('input[id="\\#ICSave"]');
64
+ await page.click('input[id="\\#ICSave"]');
65
+ await page.waitForSelector("#MTG_CLASS_NBR\\$0");
66
+ const elements = await page.$$('[id^="MTG_CLASS_NBR"]');
67
+ const classIds = new Set();
68
+ for (const element of elements) {
69
+ const classId = await page.evaluate((el) => el.textContent, element);
70
+ classIds.add(classId);
71
+ }
72
+ await page.close();
73
+ return classIds;
74
+ }
75
+
76
+ async function createRequest(browser, classId) {
77
+ const page = await browser.newPage();
78
+ await page.goto("https://extension.fullerton.edu/app/Create", {
79
+ waitUntil: "networkidle2"
80
+ });
81
+ await page.setViewport({ width: 1080, height: 1024 });
82
+ await page.type("input[name=cwid]", CWID);
83
+ await page.click(
84
+ ".MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary.MuiButton-fullWidth"
85
+ );
86
+ await page.click('input[name="ques1"][value="0"]');
87
+ await page.click('input[name="ques2"][value="0"]');
88
+ await page.click('input[name="ques3"][value="0"]');
89
+ await page.click('input[name="ques4"][value="1"]');
90
+ await page.click('input[name="ques5"][value="0"]');
91
+ await page.click('input[name="ques6"][value="1"]');
92
+ await page.click('input[name="ques7"][value="0"]');
93
+ await page.click('input[name="ques8"][value="1"]');
94
+ await page.click('input[name="ques9"][value="0"]');
95
+ await page.click('input[name="immigrationStatus"][value="4"]');
96
+ await page.click('input[name="ques10"][value="1"]');
97
+ await page.click(
98
+ ".MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary.MuiButton-fullWidth"
99
+ );
100
+ await page.type("input[name=classnbr]", classId);
101
+ await page.evaluate(() => {
102
+ const buttons = Array.from(
103
+ document.querySelectorAll(
104
+ "button.MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary"
105
+ )
106
+ );
107
+ const targetButton = buttons.find((button) =>
108
+ button.innerText.includes("REQUEST CLASS")
109
+ );
110
+ if (targetButton) {
111
+ targetButton.click();
112
+ }
113
+ });
114
+ await page.waitForFunction(
115
+ (classId) =>
116
+ document.body.textContent.includes("Class: " + classId) ||
117
+ document.body.textContent.includes("Alert"),
118
+ {},
119
+ classId
120
+ );
121
+ if (await page.evaluate(() => document.body.textContent.includes("Alert"))) {
122
+ console.log("!! Class not available !!");
123
+ await page.close();
124
+ return;
125
+ }
126
+ await page.waitForFunction(
127
+ (classId) => document.body.textContent.includes("Class: " + classId),
128
+ {},
129
+ classId
130
+ );
131
+
132
+ await page.click(
133
+ ".MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary.MuiButton-fullWidth"
134
+ );
135
+
136
+ await page.type("input[name=firstname]", FIRST_NAME);
137
+ await page.type("input[name=lastname]", LAST_NAME);
138
+ await page.type("input[name=email]", EMAIL);
139
+ await page.type("input[name=confirmemail]", EMAIL);
140
+ await page.type("input[name=phonehome]", HOME_PHONE);
141
+ await page.type("input[name=phonemobile]", MOBILE_PHONE);
142
+ await page.type("input[name=birthdate]", BIRTHDAY);
143
+ await page.select('select[name="gender"]', GENDER);
144
+ await page.type("input[name=address1]", ADDRESS_LINE_1);
145
+ await page.type("input[name=address2]", ADDRESS_LINE_2);
146
+ await page.type("input[name=city]", CITY);
147
+ await page.type("input[name=state]", STATE);
148
+ await page.type("input[name=zip]", ZIP_CODE);
149
+ await page.type("input[name=country]", COUNTRY);
150
+ await page.select('select[name="immigrationStatus"]', "10");
151
+ await page.click(
152
+ ".MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary.MuiButton-fullWidth"
153
+ );
154
+ await page.click(
155
+ ".MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary.MuiButton-fullWidth"
156
+ );
157
+ await page.click(
158
+ ".MuiButtonBase-root.MuiButton-root.MuiButton-contained.MuiButton-containedPrimary.MuiButton-fullWidth"
159
+ );
160
+
161
+ await page.waitForFunction(
162
+ () =>
163
+ document.body.textContent.includes(
164
+ "Your request for approval to enroll has been submitted successfully."
165
+ ),
166
+ {}
167
+ );
168
+
169
+ const trackingCode = await page.evaluate(() => {
170
+ const h6 = document.querySelector(
171
+ "h6.MuiTypography-root.MuiTypography-subtitle2"
172
+ );
173
+ const text = h6 ? h6.innerText : null;
174
+ const match = text ? text.match(/Tracking Code: (\w+)/) : null;
175
+ return match ? match[1] : null;
176
+ });
177
+
178
+ console.log("Tracking code:", trackingCode);
179
+
180
+ await page.close();
181
+ }
182
+
183
+ (async () => {
184
+ const browser = await puppeteer.launch({ headless });
185
+
186
+ console.log("Running for CWID " + CWID);
187
+
188
+ const classIds = await scrapeClassIds(browser);
189
+ console.log("Got class ids:", classIds);
190
+
191
+ for (const classId of classIds) {
192
+ console.log("Requesting class " + classId);
193
+ await createRequest(browser, classId);
194
+ }
195
+
196
+ await browser.close();
197
+
198
+ console.log("Done");
199
+ })();
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "csuf-en",
3
+ "version": "1.0.10",
4
+ "description": "A Puppeteer script for csuf eng101 class",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/Apromodo/csuf-eng.git"
12
+ },
13
+ "keywords": [
14
+ "puppeteer",
15
+ "automation",
16
+ "script"
17
+ ],
18
+ "author": "Kaya Unal",
19
+ "license": "MIT",
20
+ "bin": {
21
+ "csuf-eng": "index.js"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/Apromodo/csuf-eng/issues"
25
+ },
26
+ "homepage": "https://github.com/Apromodo/csuf-eng#readme",
27
+ "dependencies": {
28
+ "prompt-sync": "^4.2.0",
29
+ "puppeteer": "^21.11.0"
30
+ }
31
+ }