2026-07-08

Charles 4.x.x - Profiles 功能,快速切換一堆 map 和 rewrite

最近使用 Charles 的場景,常常不同的專案有一堆不同的 map 和 rewrite 要設定。

一開始苦於不知道怎麼一鍵切換一整組 map、rewrite、proxy 設定,後來終於發現原來可以用 Profiles 來設定:

一開始只有一個 default profile,可以 Add 新增一個 profile,使用不同的 profile 當下設定的 map、rewrite、proxy 都會保存在選取的 profile 裡。


以後不同專案就能用直接切不同 profiles 修改 map、rewrite、proxy 等各種設定了!
 

2026-05-05

[AVD] Android 步數模擬


在AVD的更多選項中,sensors 的 move,拉動 Y 軸可以模擬前後晃動,對部分 app 有模擬步數的效果。

不想一直手拉,可以用下面的指令不段重複,直到 crtl + c 離開:

trap "echo Stopped; exit" INT while true; do { echo "auth $(cat ~/.emulator_console_auth_token)" echo "sensor set acceleration 0:9:0" } | nc localhost 5554 sleep 0.1 { echo "auth $(cat ~/.emulator_console_auth_token)" echo "sensor set acceleration 0:13:0" } | nc localhost 5554 sleep 0.1 done

2026-04-29

Devlog 離職集點小卡(???

🦩㊗️🎉 大家期待(沒有人期待)的離職集點小卡上線啦!!

先上網址: https://goescat.github.io/quit-stamp-card/


 

(我後來搜尋一下發現有人做過 app 了,app 留給大神來做,幸好小的做的是網頁版。)

離職集點小卡是個非常陽春的網頁,反正就是想離職就蓋一點,還可以紀錄一下原因⋯⋯

可以不照順序蓋,但集滿30點就鼓勵你離職(??

總之是個非常銀杏、非常耐斯的工具🤪 

⚠️目前還沒有清除、重新集點功能,可以自助 F12 clear data ⋯⋯
⚠️作為趣味性的小品,資料是儲存在使用者瀏覽器的 local storage。local storage 嘛,你知道的,系統也可能清除網站資料,簡單來說資料可能遺失~

2026-01-16

Devlog 易經籌策占卦網頁 I-Ching Stalk Divination v2.0

先上網頁連結 https://goescat.github.io/i-ching-stalk-divination/ 。


-

其實我先前就做了易經籌策占卦,v1.0 還在這裡 https://goescat.github.io/iching_test.html)。



應該可以感受到 v1.0的界面非常陽春,不過最重要的是裡面取卦的方式是依照傳統籌策占卦的方式取出,沒有馬虎,所以到 v2.0這部分就沒有更動了。

-

先介紹一下占卦方式,畢竟是 P1 在 v1.0 時就完成的功能,整個工具最核心的部分XD,我從 v2.0 repo 裡的 README 複製一下:

1. 籌策占卦需要準備 50 根籌策,第一步是取出一根至於上方不動(如界面呈現)代表太極。 下方可撥動的籌策為 49 根。

2. 在心中想好問題,誠心的提問。

3. 將 49 根籌策絡在一起,從中間分一半。

4. 將左邊的籌策取出一根至於手上(程式中會將左邊絡 -1)。

5. 將左邊的籌策以4根一組做計算,剩下不足4根即取出,若都沒有剩下,即取出4根(程式中會左邊絡會減去餘數,同樣餘數為0則-4)。

6. 換右邊的籌策,不需取出一根,直接4根一組計算,取出的規則如上。

7. 三變成一爻。因此將剩下的籌策再絡在一起,從中間分一半,如上操作再進行2次(共3次,所以程式中會引導分半3次。)

8. 進行 3 次後,剩餘的組數必定為6、7、8、9其中一數。 單數為陽爻,雙數為陰爻。9為老陽,6為老陰,將變爻。(若有變爻,程式在結果會註明。) 此時得到1爻。

9. 重複上述6次,即得6爻,也就是完整的一卦。

具體操作影片可參考臺大開放式課程傅佩榮教授 影片 示範。

-

總之 v2.0我幫卦象加上了卦辭、爻辭的介紹:


總共64卦的頁面,內容都來自中國哲學書電子化計劃 http://ctext.org/zh。做完實在滿開心的。

之後應該還可以補充上怎麼解卦的說明,方便大家加減參考XDD


2025-07-30

Github Actions matrix + Pytest mark 多節點同步執行 case

隨著自動化測試的 case 越來越多,總有一天會遇到該來平行跑測試這件事。

根據使用的框架、CI/CD 工具不同,實作方式也會有所差異。這邊紀錄一下我之前用 pytest mark 搭配 GitHub Actions 做平行執行的做法。

pytest 的 mark 拿來執行一系列 case 很方便,所以放在 Github Actions 時,決定以 matrix 同時開多個同 mark 名稱的節點來執行,類似下面這樣:
strategy:
  matrix:
    mark: ['node_serviceA', 'node_serviceB', 'node_serviceC']
  fail-fast: false
記得把 fail-fast 設成 false,不然只要有一個節點先執行完,matrix 裡所有節點都會一起終止。

在後續執行的部分,就像這樣使用:
run: pytest -m ${{ matrix.mark }}

而在case裡,case function 或 class 就加上想要在哪個 node 執行,如:

@pytest.mark.node_serviceA
def test_api_service_a():
#...

Github Actions 的收費會看執行時間,執行時間在 matrix 就是看所有節點各別都花了多少時間(等於同時多開n台),所以費用和原先不會有差異。

2025-07-27

Devlog 離職遺照產生器 v1.0

分享在FB之後,最多的回饋就是需要RWD。也是啦,這個時代哪有人還在用電腦版網站呢(淚

於是快速的加上了簡單的 RWD~目前長這樣(標題也偷改了):


把背景小故事收到了「這是啥?」裡面,點開來之後,點「不要幹話」可以收合!



另外加入了照片滿版、裝飾置中的功能~

照片滿版 demo

(圖片為 ChatGPT 生成的「我」,不過與實物不能說一模一樣,只能說毫無關聯):


裝飾置中 demo



雖然說手機版的圖片編輯,應該要加上適合手機的手勢操作(雙指捏合縮放、旋轉等),但因為如果要加上手勢操作會需要整個大改寫,所以暫時還沒加。

還有收集到其他需求,像是直接轉成黑白照片、自己輸入文字等,之後有空再更新~

-

上面都是使用者回報的部分,直到我多加了一些圖片之後,才發現了一個超級嚴重的問題⋯⋯

完全忘記圖片要壓縮,有些圖片大小甚至有 1MB 之多⋯⋯我都在家裡超快的網路上測試,完全忽略了圖片出來超慢,而且有點耗使用者的網路流量QQ

於是修正了用 webp 讓圖片都降到 100KB 以下,加入 prefetch catch。

-

另外調整了一下裝飾品的順序,一開始是加入的先後順序,後來是只要點擊選中的裝飾品就要到最上面,感覺更直覺一點。

-

最後總結一下學到的、印象深刻的東西:

  • 圖片要壓縮
  • 承上,測試的時候記得用 F12 network throttling 注意一下不同網路狀況,應該能及早發現

2025-07-24

Devlog 離職照片產生器 v0.1

最近有一些奇妙的體悟,讓我好像比較有動力做一些不同的東西。

一是覺得 vibe coding 做一些小東西真的很有趣、很方便,大幅節省了原本沒有 AI 前,完全不熟某種開發時,要稍微搜尋,大致知道用什麼工具比較適合、選了可能還要寫出一部份試試的時間。似乎可以把以前想做,但一直用「沒時間」當藉口的東西都做出來了。另外 AI 也省掉很多原本工作上的苦工,有時間做一些真正重要的事之外,還有時間想一些工作之外好玩的東西。

二是最近剛好受到了滿多類似的鼓勵,大意是「一個軟體的生命是在上線後,有人使用才開始」,以前覺得有點雞湯,但後來覺得也是事實。以前覺得自己工作之外做的東西不管是主題(可能我感興趣的東西太怪)還是介面之類的都很鳥⋯⋯實在不敢拿出來,但是現在想想,我不過就只是要做一個自己覺得有趣的東西,根本不用先想這麼多。

先求有再求好。紀錄各種過程,一定是很有趣而且很有收穫的一件事。

-

前幾天 FB 回顧我上一份工作離職的紀念貼文。當時我把 slack 頭像換成像是遺照的樣子,同事問我這是哪裡來的產生器。於是我當時想說來做個產生器好了!一等就是一年——直到現在終於想起來,然後速速做了0.1版~

-

請看這精(ㄐㄧㄢˇ)美(ㄌㄡˋ)的介面:



對不起我沒有前端的天賦,不過人生還很長,以後會慢慢改善。

不要看它醜,該有的東西都有(因為用了fabric.js,人家都寫好惹),請看 demo:

上傳照片的部分這裡先跳過,如上圖,可以選擇位置固定的緞帶,還有多個可以任意擺放、縮放、選轉的裝飾品。
滿意之後,可以下載編輯完成的照片~

-

做到目前這樣,在電腦上看算是功能都有出來,堪用(寬鬆標準)。
但是在手機上沒有RWD,而且對於物品的操作會感覺很不直覺,之後還有很多可以改善的空間。

-

最後總結一下學到的、有印象的東西:
  • 回憶起在 local file:// 測試會遇到 CROS error。因為平常寫 python,所以在目錄下 python -m http.server 8000 就可以。
  • 當時花了比較多時間調整照片和新增上面的緞帶、裝飾品時怎麼樣會比較直覺一點。比方最基本的,一新增裝飾品,裝飾品應該就要被選中。原本用了send to front 之類的方式,但其實沒有用,其實被選中就會出現在最上方了。
  • 因為照片容易不小心點到就跑上來,所以我新增了一個「照片到最下面」的按鈕。目前完全是以能最快開發完來設計😂覺得這樣子的過程也很有趣,可以體會到為什麼有些趕鴨子上架的產品,在缺少規格時有很多突兀的設計。
  • 下載的部分,發現手機的網頁上 link.click() 是無效的,所以後來是開新分頁顯示圖片,讓使用者長按圖片存檔。忽然知道為什麼手機小測驗存圖片都是長按儲存,自己做過才知道😂
之後有更新再紀錄~

2025-05-12

Selenium Chrome WebDriver 定位 之2

之前在 Selenium Chrome WebDriver 定位 有記錄過 Chrome 模擬定位,但前陣子遇到 CDP 送了定位但沒有用的情況。 

所以我實際使用 Chrome 送一次 CDP command 試試。 

1. 首先,允許網站定位。 
2. 接著在開發者工具中找到 Protocol Monitor(沒有開啟過的話,需要先去 Settings > Experiments > Protocol Monitor 勾選)。 

然後試著在有問題的頁面送 CDP command⋯⋯ 
這時候我發現 Protocol Monitor 有 target 可以選擇;我遇到「送了定位但沒有用」的頁面中有很多 target。

或許是沒有指定時,我 CDP command 沒有送到 main。 

-

看了一下官方文件怎麼指定 target。

1. 先用 Target.getTargets 取得所有 target:
driver.execute_cdp_cmd("Target.getTargets", {})
會得到一個 object。 

2. 拿到你要的 url 的 targetId 之後,attachToTarget 得到 session id:
driver.execute_cdp_cmd("Target.attachToTarget", {
    "targetId": target_id,
    "flatten": True
})
3. 現在就可以送 CDP command 給特定 target 了:
"Emulation.setGeolocationOverride", {
                "latitude": lat,
                "longitude": lng,
                "accuracy": 10,
                "sessionId" : session_id
            }

2025-04-04

自動測試的其他操作元素方式 - 使用 execute_script 執行 JavaScript 操作 DOM

在進行 click、input、scroll 等操作時,有時會遇到元素無法或很難操作的情況。這時可以考慮使用 WebDriver 的 execute_script() 執行 JavaScript 操作 DOM。

以下整理一些常見範例:

選取元素


  • 使用 ID 選取

document.getElementById("example");


  • 使用 class name 選取

document.getElementsByClassName("example");


  • 使用 name 選取

document.getElementsByName("example");


  • 使用 CSS 選取

document.querySelector("[attribute='value1']"); // 選取第一個符合的元素

document.querySelectorAll("input[attribute='value2']"); // 選取所有符合的元素


  • 使用 tag name 選取

document.getElementsByTagName("input"); // 選取所有 input 元素


  • 使用 XPath 選取

document.evaluate("//*[text()='example']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;


操作元素

選取後可進行修改、點擊、滾動等操作。


  • 點擊元素

document.getElementById("example").click();


  • 點擊多個元素中的其中一個

var a = document.getElementsByClassName("ui example button");

a[2].click(); // 選取第三個符合的按鈕並點擊


  • 修改 value 值

document.getElementById("example").value = "20";


修改其他 attribute 的值

  • document.getElementById("Mobility").selectedIndex = 12; // 設定 select 選擇的索引值


  • 移除屬性

document.getElementsByName("example")[0].removeAttribute("hidden"); // 移除 hidden 屬性


  • 捲動元素到視窗可見範圍

arguments[0].scrollIntoView();


  • 捲動元素到視窗中間

arguments[0].scrollIntoView({ block: 'center' });


⋯⋯

總之 JS 有的都可以用。

execute_script  不僅限於不能操作時才用得到,像是想要觀察游標位置等,也可以用 JS 顯示游標的移動。

但 execute_script 並不是真正的操作,所以在以 event 判斷的頁面,可能表面看起來操作成功,但實際上並未觸發預期效果。

2025-03-18

Github Actions cron 排程

之前在 Github Actions 上設定排程的時候,為了測試方便,設定了2分鐘,然後發現過了10幾分鐘都沒有執行。

查了一下才發現,文件上說,workflow 可以執行的最短間隔是5分鐘,而且在負載較高的時候可能會延後,也可能被跳過。

可以從 Actions → All workflows →  Status 選 Skipped,確認 workflow 是否真的被跳過。   

-

補充個人實際經驗,有遇過 cron 延後30分鐘才執行。


2025-03-16

Chrome 開發者工具 console 拿 xpath 階層下所有元素的 text

每個人習慣的抓 xpath 的插件不太一樣。
但是假如不想用任何插件,Chrome 的開發人員工具其實很夠用了。
像是大家都知道的,在開發人員工具 > console 中輸入:

  $x("//*[text()='隨便一個範例的 xpath']") 

可以用來確認 xpath 是否有選到元素、選到幾個元素等。

要確認文字也很容易,一般只要「這個」xpath 本身的文字的話,直接看 element 就可以了,但確認的場景可能是想取得這個 xpath 下「所有階層」的文字。
可以像這樣:

$x("xpath").map(el => el.innerText || el.textContent);

至於 innerText 和 textContent 有什麼差異,可能之後再筆記一下。

2025-03-01

[Mac] Python venv 設定

1. 到你想要放 venv 的路徑
2. python venv venv_name 
(看你 python 怎麼裝,可能要 python3 -m venv venv_name)
這樣就有叫 venv_name 的資料夾了
3. source venv_name/bin/activate
就可以使用這個 venv

deactivate可以離開

2024-12-18

Selenium Chrome WebDriver 進行定位模擬

直接上範例 code:
from selenium import webdriver
import time

# 設定位置的經緯度,以大慶夜市為例
latitude = 24.122629
longitude = 120.655638
accuracy = 10

driver = webdriver.Chrome()

# 用 CDP command 設定座標經緯度
driver.execute_cdp_cmd(
    "Emulation.setGeolocationOverride",
    {
        "latitude": latitude,
        "longitude": longitude,
        "accuracy": accuracy
    }
)

# 打開頁面試試看定位,這裡以 OpenStreetMap 為例
driver.get("https://www.openstreetmap.org/")
driver.find_element("css selector", "span.geolocate").click()

# 給你看個10秒
time.sleep(10)

driver.quit()
Emulation.setGeolocationOverride 中的 latitude、longitude、accuracy 對於定位來說都是「必要」參數,雖然官方文件寫 optional,但也特別說缺少任一個,定位就不會作用XD

latitude、longitude 分別是緯度和經度,沒什麼問題。比較需要解釋的是 accuracy 定位精確度,通常帶1或以上即可。accuracy 的單位是公尺,「越小越準確」。但最好不要為0,0是不準確時回傳的(有些網站可以接受,也有些不接受)。

因為定位通常由系統回傳,我找到了Android 取得 accuracy 的文件,解釋了定位精確度。簡單來說,從經緯度的點為中心,畫一個半徑等於此精準度的圓,實際位置有 68% 的機率落在該圓內。(iOS 似乎不是這樣定義,不過總體來說也是越小越精確。)

直接以 OpenStreetMap 為例,當 accuracy 是10的時候,我還知道我在大慶夜市的哪個攤位:


當 accuracy 是100,定位超級飄,在這個圈圈裡都可能是實際定位,我可能根本不在大慶夜市裡了:

同場加映,accuracy 是 0,OSM 可以定位:

沒有 accuracy,提示:Geolocation error: position unavailable.


另外補充:
  • 模擬定位在 headless (無頭)模式也可以正確定位,之前看到一些資訊說不行,那很可能是其他問題。
  • web driver 如果禁用定位,例如 options 時禁用:
    options.add_experimental_option(
        "prefs", {"profile.default_content_setting_values.geolocation": 2}
    )
    模擬定位就不能使用。
  • 可以先用 CDP command 加上權限:
    driver.execute_cdp_cmd(
        "Browser.grantPermissions",
        {
        "permissions": ["geolocation"],
        } )
    再設定定位。
  • Google Maps 也可以使用這樣來定位。有些資訊說 Google Maps 以 IP 定位,但實際上是剛載入時抓 IP 位置的國家(OSM也會這樣),而當要精確定位目前位置時,會使用裝置位置,也就是 Emulation.setGeolocationOverride 模擬的座標。
-

目前 Chrome 的許多開發者工具都可以透過 CDP(Chrome DevTools Protocol) 指令來完成。具體有哪些功能可以看看官方文件:https://chromedevtools.github.io/devtools-protocol/


2024-11-28

Postman (newman) 到 Github actions 上的一些小記錄

前陣子遇到一個需求,團隊的 API 測試放在 postman 上,所以想要試試讓 Postman 放在 Github Actions 上面執行。當時花蠻多時間的,紀錄一些過程。
 
1. 在 Postman CLI 和 Newman 做選擇
 
Postman CLI 是官方提供的 CLI 套件,而 Newman 是社群維護的。
一開始我先用了 Postman CLI。
畢竟是官方提供,整合做得很好。有些 API 測試時需要上傳的檔案,有在 postman 上傳過並儲存在 postman cloud 的話,都可以直接使用。而測試結果直接顯示在 Postman 的 Runs 裡面——
沒想到這竟然是個缺點,它的 reporter 不能自訂,唯一的 report 就是要去剛剛提到的 Runs 裡面看,不然就是直接來自執行時的 CLI ⋯⋯(來源參考 https://community.postman.com/t/postman-cli-reporting/66763)
 
所以就因為 Newman 可以自訂 reporter,直接選了 Newman XDDDD
 
2. 上傳檔案的測試
 
用了 newman 也不是就一帆風順。
比方上傳檔案的話有點麻煩,要匯出 collection 之後填上檔案路徑。
這比起用 Postman CLI 麻煩多了。原先在 postman 改完 collection 裡的任何部分之後執行就能生效。但為了讓 Newman 上傳檔案,用匯出的 collection 就沒辦法了QQ
 
3. 執行失敗的 log
 
當時還有一點痛苦的,就是失敗時沒有 response 的 log ⋯⋯Postman CLI 也一樣。
可以做到的方法大致上是在每一個 API 的 post-script 加上紀錄:
pm.test("Response status code is 200", function () {
    if (pm.response.code !== 200) {
        throw new Error(`Response Code: ${pm.response.code} | Response Body: ${pm.response.text()} | Request Body: ${JSON.stringify(pm.request.body)}`);
    }
    pm.response.to.have.status(200);
});;


總之成功在 Actions 上跑了一段時間,不過後來還是決定換成自己寫的 API 框架了。謹此紀念沒跑多久的 Postman 上 Github Actions 經歷XDD

2024-11-25

Selenium 4.6 之後你真的不用下載 webdriver 或使用 WebDriverManager

如題。

在 Selenium 4.6 之後,已經不用另外下載 webdriver,不用帶路徑,不用使用 WebDriverManager 解決下載和帶路徑的問題。

你只需要:

from selenium import webdriver
driver = webdriver.Chrome()
這樣就可以跑了!預設是目前的 stable 版本。

-

如果你需要特定版本的 chrome,可以用Options指定,selenium manager 會自動下載你指定的版本:

options = webdriver.ChromeOptions()
options.browser_version = '120'
driver = webdriver.Chrome(options=options)

除了特定版本號,也可以帶標籤如stable(目前 CfT 版本)、beta(下一個版本穩定)、dev(目前正在開發版本)、canary(為開發人員每晚建置)、esr(擴充支援版本,僅用於 Firefox)。

2024-11-19

Selenium + ChromeDriver - 開啟 DevTools 的行動裝置模式

在 Google Chrome 瀏覽器的 F12 開發工具中,有個很方便的行動裝置模式,可以模擬網站在行動裝置上的顯示和行為。在測試為手機、平板設計的網站時非常好用!
 
在自動化的時候也可以用 add_experimental_option 來設定 webdriver 開啟行動裝置模式,上個最小 Python 範例:

from selenium import webdriver

mobile_emulation = { "deviceName": "iPhone 12 Pro" }
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
driver = webdriver.Chrome(options=options)

deviceName 具體有哪些 device,可以看一下自己的 Chrome 有哪些內建的裝置可以使用:
點擊上面選單的 Edit,還有更多的裝置,也可以新增自己設定:

至於在 code 裡可以用類似下面的方式來設定自己需要的裝置設定:

from selenium import webdriver

mobile_emulation = {
    "deviceMetrics": { "width": 360, "height": 640, "pixelRatio": 3.0 },
    "userAgent": "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
    "clientHints": {"platform": "Android", "mobile": True} 
}
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
driver = webdriver.Chrome("/driver/path", options=options)

2024-11-14

Appium iOS - 你確定 build 了 simulator 可以執行的 app,但還是一直噴錯怎辦?要不要用一下 bundleId?

事情是這樣的,我和開發拿到了可以給 simulator 執行的 .app 檔案。
直接拖曳 app 丟到 simulator 裡它可以順順打開、可以妥妥操作。

但是當我用 Appium 以這個 capability 開 app 就出4了:
  "appium:deviceName": "iPhone 15 Pro",
  "appium:automationName": "XCUITest",
  "platformName": "iOS",
  "appium:platformVersion": "17.5",
  "appium:app": "/Users/username/Desktop/folder/Demo.app" 
}

會遇到錯誤: Failed to create session. An unknown server-side error occurred while processing the command. Original error: The com.testdomain.test-demo-ios.dev application does not support the x86_64 Simulator architecture: Non-fat file: /Users/username/Desktop/folder/Demo.app/Demo is architecture: arm64 Please rebuild your application to support the x86_64 platform. 

為什麼?為什麼???直接裝也可跑啊?人家真的就有 support x86_64 啊。
我問天——我問天——甘會當莫創治—— 

然後啊,在我跟開發確認了幾次,很怕被揍的時候,我才想到我先在 simulator 安裝好就可以用 bundleId 開啟嘛:
  "appium:deviceName": "iPhone 15 Pro",
  "appium:automationName": "XCUITest", 
  "platformName": "iOS",
  "appium:platformVersion": "17.5", 
  "appium:bundleId": "com.testdomain.test-demo-ios.dev"
}

太好了,太好了!
流程上不同的大概只有要先指令裝 app,需要的話加個 reset capability。

ADB - 從裝了 app 的手機拿到 apk 檔

有些時候在實體機上裝了 app,想拿到模擬器上安裝。這個時候複製檔案的 adb pull 就很好用!

首先找到你想抓的 app 安裝在哪:
adb shell "pm list packages -f | grep 你想抓的Package名稱" 

以下舉例,假設我想找蝦皮 app,在終端機輸入:
adb -d shell "pm list packages -f|grep shopee" 

會回傳:
package:/data/app/com.shopee.tw.int-X1xsowqyHAerEoslb2fxj00g==/base.apk=com.shopee.tw.int 

那個 /data/app/com.shopee.tw.int-X1xsowqyHAerEoslb2fxj00g==/base.apk 就是 app 安裝的位置!
把 app 拉到你現在終端機的工作路徑下:
adb pull /data/app/com.shopee.tw.int-X1xsowqyHAerEoslb2fxj00g==/base.apk 

現在你就有 base.apk 了!
不出意外的話,你可以把 base.apk 裝在你的模擬器上使用~

2024-11-11

Appium Android 起手式 - 取得 appPackage 和 appActivity

在使用 Appium 進行 Android 自動化測試時,appPackage 和 appActivity 是必要的參數。

取得方式很多,記錄一下我習慣用的方法:
adb shell dumpsys window | grep -E "mCurrentFocus"
確定已經連到了 Android 裝置,並開啟 app,輸入上面的指令。

回傳的結果會是目前開啟的 app 和 app 頁面,如:appPackage/appActivity 的格式的資訊。

實際例子,開啟 Chrome app 之後: mCurrentFocus=Window{1c35821 u0 com.android.chrome/com.google.android.apps.chrome.Main} appPackage 是 com.android.chrome,appActivity 是 com.google.android.apps.chrome.Main。
-
要注意的是,appActivity 是能進 app 的第一個畫面,有些 app 開啟時可能閃現一下就跳到下一個畫面。沒有找到正確的可能會有類似以下的錯誤:
exited with code 255'; Command output: Exception occurred while executing 'start': java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000
這種時候可以拼手速,在一開啟載入閃現那個第一個畫面就趕快 enter 指令,但也可以用 Android Studio 或其他編輯器打開 apk 檔的 AndroidMainfest.xml,找到含有 android.intent.action.MAIN 的 Activity。
實際例子,有個 Activity 有這樣的內容 :
<activity
    android:name="com.example.app.loading.LoadingActivity"
    android:exported="true"
    android:screenOrientation="1"
    android:hardwareAccelerated="false">

    <intent-filter>
        <action
            android:name="android.intent.action.MAIN" />
        <category
            android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity>
那就是這個 Activity 了!

2024-11-06

Appium 2.0 錯誤 Could not find a driver for automationName 'xxxxxx' and platformName 'xxxxxx'

剛升到 Appium 2.0 執行以前的 code 可能會遇到錯誤:
could not find a driver for automationname 'uiautomator2' and platformname 'android'

因為 Appium 2.0 版本開始,driver(例如 uiautomator2、xcuitest 等)都變成獨立的套件,需要單獨安裝。

安裝:
appium driver install uiautomator2 

確認安裝了哪些 driver:
appium driver list 

會顯示你目前裝了什麼和沒裝什麼:
✔ Listing available drivers
- uiautomator2@3.8.1 [installed (npm)]
- xcuitest [not installed]
- espresso [not installed]
- mac2 [not installed]
- windows [not installed]
- safari [not installed]
- gecko [not installed]
- chromium [not installed]

裝自己要用到的就好! 

另外 appium driver list 有參數可以只看有裝的 driver:
appium driver list --installed

會顯示: 
✔ Listing installed drivers 
- uiautomator2@3.8.1 [installed (npm)] 

裝完之後,如果你原本有跑 appium server,記得重開才會生效~